Java开发入门到精通 -- 面向对象概述与封装性
小职 2021-10-19 来源 :「庸人冲」原文链接:https://blog.csdn.net/weixin_48084293/ar 阅读 339 评论 0

摘要:本篇主要介绍了Javak开发入门到精通 -- 面向对象概述与封装性,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

本篇主要介绍了Javak开发入门到精通 -- 面向对象概述与封装性,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

Java开发入门到精通 -- 面向对象概述与封装性

面向对象思想

概述

Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下,使用Java语言去设计、开发计算机程序。 这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为。面向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,描述成计算机事件的设计思想。 它区别于面向过程思想,强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。


面向过程与面向对象的区别

面向过程:当需要实现一个功能时,每一个具体的步骤都要亲历亲为,详细处理每一个细节。


面向对象:当需要实现一个功能时,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我们做事。


举例

洗衣服:


面向过程:把衣服脱下来–>找一个盆–>放点洗衣粉–>加点水–>浸泡10分钟–>揉一揉–>清洗衣服–>拧干–>晾起来


面向对象:把衣服脱下来–>打开全自动洗衣机–>扔衣服–>按钮–>晾起来


区别

面向过程:强调步骤。


面向对象:强调对象,这里的对象就是洗衣机。


代码展示

public class Demo01PrintArray {

    public static void main(String[] args) {

        int[] arr = {1,2,3,4,5};

        // 要求打印格式为:[1, 2, 3, 4, 5]


        // 面向过程实现

        System.out.print("[");

        for(int i = 0; i < arr.length; i++){

            if(i < arr.length - 1) {

                System.out.print(arr[i] + ", ");

            } else {

                System.out.println(arr[i] + "]");

            }   // 需要关注功能实现的每一个细节

        }


        System.out.println("===============");


        // 面向对象实现

        System.out.println(Arrays.(arr));

        // 不需要关注功能实现的每一个细节,只需要调用具有这个功能的方法即可。

        //Arrays.toString() 

        //JDK提供的Arrays类中的toString() 方法

        //Arrays.toString() 可以将数组转换成字符串格式

    }

}


Java开发入门到精通 -- 面向对象概述与封装性


特点

面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。面向对象的语言中,包含了三大基本特征,即封装、继承和多态。


面向对象三条主线

类及类的成员:属性(成员变量)、成员方法、构造器、代码块、内部类。

面向对象三大特性:封装、继承、多态。

其它关键字:this, super, abstract, interface, final, package, import…

类和对象

什么是类

类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。


现实中,描述一类事物:


属性:就是该事物的状态信息。


行为:就是该事物能够做什么。


举例:小猫。


属性:名字、体重、年龄、颜色。


行为:走、跑、叫。


什么是对象

对象:是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。


现实中,一类事物的一个实例:一只小猫。


举例:一只小猫。


属性:tom、5kg、2 years、yellow。


行为:溜墙根走、蹦跶的跑、喵喵叫。


类与对象的关系

类是对一类事物的描述,是抽象的。


对象是一类事物的实例,是具体的。


类是对象的模板,对象是类的实体。


Java开发入门到精通 -- 面向对象概述与封装性


类的定义

事物与类的对比

现实世界的一类事物:


属性:事物的状态信息。


行为:事物能够做什么。


Java中用class描述事物也是如此:


成员变量:对应事物的属性


成员方法:对应事物的行为


类的定义格式

public class ClassName {

    //成员变量

    //成员方法

}


定义类:就是定义类的成员,包括成员变量和成员方法。


成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外,也叫类的属性,field。


成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。


/*

定义一个类,用来模拟"学生",其中就有两个组成部分:

1、属性(是什么):

    姓名、年龄、性别、...

2、行为(能做什么):

    吃饭、睡觉、学习、...


对应到java的类当中:

1、成员变量(属性):

    String name;  // 姓名

    int age;      // 年龄

    byte sex;     // 性别 0:女,1:男,2:保密

2、成员方法(行为):

    public void eat() {}    // 吃饭

    public void sleep() {}  // 睡觉

    public void study() {}  // 学习

 */


public class Student {

    // 成员变量

    String name;  // 姓名

    int age;      // 年龄

    byte sex;     // 性别


    // 成员方法

    public void eat(){

        System.out.println("吃!");

    }


    public void sleep() {

        System.out.println("睡!");

    }


    public void study() {

        System.out.println("学!");

    }

}


对象的使用

使用步骤

通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用,具体分为以下三个步骤:


导包:指出需要使用的类在什么位置。


如果类同属于一个包中(同一路径下),可以省略导包语句。


// 导包语句

// import packageName.className;

import cn.study.day07.demo03.Demo02Student;


创建

// className objName = new className();

Student stu = new Student();


使用

使用成员变量


// objName.memberVarName

stu.name = "张三";


使用成员方法


// objName.memberMethName(para,...)  para可以是0或多个

stu.eat();


总结:想用谁,就用对象名点儿谁。


代码举例

例一

public class Demo02Student {


    public static void main(String[] arg){

        // 1. 导包

        // 需要使用的Student类,和当前所在类同属一个包下,可以省略导包语句。


        // 2. 创建

        // className objName = new className();

        Student stu = new Student();

        // 根据Student类创建了一个stu的对象。


        //3. 使用其中的成员变量

        System.out.println(stu.name);   // null

        System.out.println(stu.age);    // 0

        System.out.println(stu.sex);    // '\u0000'

        // Student类中没有给成员变量赋值

        // 默认值与数组的规则相同

        System.out.println("=====================");


        // 改变对象当中的成员变量内容

        stu.name = "张三";

        stu.age = 18;

        stu.sex = '男';

        System.out.println(stu.name);   // 张三

        System.out.println(stu.age);    // 18

        System.out.println(stu.sex);    // 男


        System.out.println("=====================");

        // 使用成员方法

        stu.eat();

        stu.sleep();

        stu.study();

    }

}


例二

/*

定义一个类,用来模拟"手机"事物


属性:品牌、价格、颜色...

行为:通话、短信...


对应到类当中:

成员变量(属性)

    String brand;

    double price;

    String color;

成员方法(行为)

    public void call(String who) {}  // 打电话

    public void sendMessage() {}     // 群发短信

*/

public class Phone {

    //成员变量

    String brand; // 品牌

    double price; // 价格

    String color; // 颜色


    //成员方法

    public void call(String who){

        System.out.println("给" + who + "打电话");

    }

    public void sendMessage() {

        System.out.println("群发短信");

    }

}


public class Demo03PhoneOne {

    public static void main(String[] args) {

        // 根据Phone类,创建一个名为one的对象;

        Phone one = new Phone();

        System.out.println(one.brand);   // null

        System.out.println(one.price);   // 0.0

        System.out.println(one.color);   // null


        System.out.println("===================");

        // 给对象当中的成员重新赋值

        one.brand = "小米";

        one.price = 998.0;

        one.color = "黑色";


        System.out.println(one.brand);   // 小米

        System.out.println(one.price);   // 998.0

        System.out.println(one.color);   // 黑色


        System.out.println("===================");

        one.call("雷军");

        one.sendMessage();

    }

}


成员变量默认值

成员变量如果未赋值,将会有一个默认值,规则如下:


整数类型,默认为0;

浮点类型,默认为0.0;

字符类型,默认为'\u0000' ;

布尔类型,默认为false;

引用类型,默认为null。

对象内存图

jvm内存划分图

Java开发入门到精通 -- 面向对象概述与封装性


一个对象的内存图

Java开发入门到精通 -- 面向对象概述与封装性


堆中的成员变量是参考方法区.class中成员变量的信息创建的,其中的值就保存在堆(Heap)中。


堆中的成员方法保存的是一个地址值,指向了方法区中的成员方法信息。


进栈也叫压栈,先进栈的在后进栈的下面,后来的压着先来的。


出栈也叫弹栈,当方法执行完毕后会立刻从栈中销毁,main方法执行完毕,则程序结束。


先进后出,后进先出。


两个对象引用指向不同对象空间的内存图

对象名,也叫对象引用

Java开发入门到精通 -- 面向对象概述与封装性



从上图可以看到,两个对象在创建时,分别在堆区开辟了不同的内存空间,各自保存着本对象的成员变量和成员方法,但是这两块堆区内存空间同时指向了方法区里同一块空间。也就是它们的所具有的属性和功能是完全相同的,不同的是成员变量的值和成员方法调用的参数。


这会出现一个问题,每创建一个对象就需要在堆中开辟一块内存空间,但是里面保存的信息基本相同,因此十分浪费内存空间。


两个对象引用指向同一对象空间的内存图

Java开发入门到精通 -- 面向对象概述与封装性


对象在方法中的使用

使用对象类型作为方法的参数

任何数据类型都能作为方法的参数。


对象引用作为参数传递给方法的是对象的地址值。


public class Demo04PassObjParam {

    public static void main(String[] args) {

        Phone one = new Phone();

        one.brand = "小米";

        one.price = 998.0;

        one.color = "土豪金";

        mothod(one); // 传递的对象的地址

        System.out.println(one);


    }


    public static void mothod(Phone param){

        System.out.println(param);

        System.out.println(param.brand);  // 苹果

        System.out.println(param.price);  // 998.0

        System.out.println(param.color);  // 土豪金

    }

}

Java开发入门到精通 -- 面向对象概述与封装性


Java开发入门到精通 -- 面向对象概述与封装性


使用对象类型作为方法的返回值

使用对象类型作为方法的返回值时,返回的是对象的地址值。


public class Demo05PhoneReturn {

    public static void main(String[] args) {

        // 用对象类型接收返回值

        Phone two = getPhone();

        System.out.println(two.brand);  // 小米

        System.out.println(two.price);  // 799.0

        System.out.println(two.color);  // RoseGold

    }


    public static Phone getPhone() {

        Phone one = new Phone();

        one.brand = "小米";

        one.price = 799.0;

        one.color = "RoseGold";

        return one;

    }


}

Java开发入门到精通 -- 面向对象概述与封装性


成员变量和局部变量的区别

定义的位置不一样


局部变量:在方法的内部


成员变量:在方法的外部,直接写在类当中。


作用域不一样


局部变量:所在方法中可以使用,出了所在方法就不能使用。


成员变量:整个类全都可以通用。


默认值不一样


局部变量:没有默认值,要使用,必须先赋值。


成员变量:如果没有赋值,会有默认值,规则和数组一样。


内存的位置不一样


局部变量:位于栈内存。


成员变量:位于堆内存。


声明周期不一样


局部变量:随着方法进栈而创建,随着方法出栈而销毁。


成员变量:随着对象创建而创建,随着对象被垃圾回收而消失。


权限修饰符的使用不同,public、 protected、 缺省、 private


局部变量:不能使用权限修饰符。


成员变量:可以使用权限修饰符。


public class Demo01VariableDifference {


    String name; // 成员变量


    public void methodA(){

        int num = 20; // 局部变量

        System.out.println(num);

    }


    public void methodB(int param) { //参数就是局部变量

//      System.out.println(num); // 错误,num是methodA方法中的局部变量,不能在methodB中使用

        System.out.println(name);  // 成员变量,类中都可以使用

        int age;  // 局部变量

//      System.out.println(age);   // 局部变量未赋值不能使用

        // 参数在方法调用时,必然会被赋值

        System.out.println(param); // 这种写法没有问题

    }

}


练习

创建一个学生类,三个属性,学号,年级和成绩。


创建20个学生类,其中学号从1开始到20结束,年级和成绩随机赋值。


Student类


// Student类

package cn.study.day26.demo05;


public class Student {

    private int number = id;  // 学号

    private int state;        // 年级

    private int score;        // 成绩

    private static int id = 1;    // 自增id


    // 无参构造器

    public Student() {

        ++id;

    }

    // 有参构造器,number和id变量自增,不允许设置

    public Student(int state, int score) {

        this.state = state;

        this.score = score;

    }


    public String stuInfo() {

        String info = "学号:" + this.getNumber() + ", 年级:" +this.getState() + ", 成绩:" + this.getScore();

        return  info;

    }


    // Getter/Setter

    public int getNumber() {

       return this.number;

    }


    public int getState() {

        return state;

    }


    public void setState(int state) {

        this.state = state;

    }


    public int getScore() {

        return score;

    }


    public void setScore(int score) {

        this.score = score;

    }

}



工具类


// 工具类

package cn.study.day26.demo05;

public class Utility {

    // 遍历打印学生信息


    /**

     * @Description 遍历Student数组,并打印数组中学生对象的信息

     * @author Joker

     * @param stus  要遍历的数组

     */

    public static void traverseStu(Student[] stus) {

        for (int i = 0; i < stus.length; i++) {

            System.out.println(stus[i].stuInfo());

        }

    }



    /**

     * @Description 筛选出Student数组中指定年级学的信息,并打印。

     * @author Joker

     * @param state 需要筛选出来的年级

     */

    public static void searchStu(Student[] stus, int state) {

        for (int i = 0; i < stus.length; i++) {

            if (stus[i].getState() == state) {

                System.out.println(stus[i].stuInfo());

            }

        }

    }


    /**

     * @Description 使用冒泡排序算法,按照成绩属性给Student数组排序,从小到大。

     * @author Joker

     * @param stus  要排序的数组

     */

    public static void bubbleSortStus(Student[] stus) {

        for (int i = 0; i < stus.length - 1; i++) {

            boolean flag = true;

            for (int j = 0; j < stus.length - 1 - i; j++) {

                if (stus[j].getScore() > stus[j + 1].getScore()) {

                    Student temp = stus[j];

                    stus[j] = stus[j + 1];

                    stus[j + 1] = temp;

                    flag = false;

                }

            }

            if(flag){

                break;

            }

        }

    }


    // 按年级快速排序


    /**

     * Description 使用快速排序算法,按照年级属性给Student数组排序,从小到大

     * @author Joker

     * @param stus 要排序的数组

     */

    public static void sortStus(Student[] stus){

        quickSort(stus, 0, stus.length - 1);

    }


    // 快速排序

    private static void quickSort(Student[] stus, int low, int high) {

        int pivot = low;

        if(low < high) {

            pivot = partition(stus, low, high);

            quickSort(stus,low,pivot - 1);

            quickSort(stus,pivot + 1, high);

        }

    }


    // 确定基轴值位置

    private static  int  partition(Student[] stus, int low, int high) {

        int pivotKey = stus[low].getState();

        while(low < high) {

            while(low < high && stus[high].getState() >= pivotKey){

                high--;

            }

            swap(stus,low,high);

            while (low < high && stus[low].getState() <= pivotKey){

                low++;

            }

            swap(stus,low,high);

        }

        return low;

    }


    // 交换两个对象引用

    private static void swap(Student[] stus, int low, int high) {

        Student temp = stus[low];

        stus[low] = stus[high];

        stus[high] = temp;

    }

}



测试类


// 测试类

package cn.study.day26.demo05;

public class StudentTestDrive {


    public static void main(String[] args) {

        Student[] stus = new Student[20];

        for (int i = 0; i < stus.length; i++) {

            stus[i] = new Student();

            // stata = [1,6]

            // score = [0,100]

            // 随机数计算公式[a,b]

            // Math.random * (b - a + 1) * a;

            int state = (int) (Math.random() * (6 - 1 + 1) + 1);

            int score = (int) (Math.random() * (100 + 1));

            stus[i].setState(state);

            stus[i].setScore(score);

        }


        // 按年级筛选学生

        System.out.println("==========按年级筛选==========");

        Utility.searchStu(stus,3);



        // 按成绩冒泡排序

        System.out.println("==========按成绩排序==========");

      Utility.bubbleSortStus(stus);

        Utility.traverseStu(stus);  // 遍历打印学生信息



        // 按年级快速排序

        System.out.println("==========按年级排序==========");

        Utility.sortStus(stus);

        Utility.traverseStu(stus);   // 遍历打印学生信息

    }


}


方法

方法重载

概念

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数、参数类型或者参数顺序不同即可。


特点

与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数、参数类型或参数顺序),调用时,可以根据传传递的实参类型、个数、顺序来调用对应的方法。


可变形参的方法

JavaSE5.0 中提供了VarArgs(variable number of arguments) 机制,允许直接定义和能多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。


格式

权限修饰符 返回值类型 方法名(数据类型 ... 参数名) {}

1

使用

当调用可变个数形参的方法时,传入的参数个数可以是 0,1,2... 多个


但是传入的参数必须与形参中的类型保持一致。


可变个数形参的方法与本类中方法名相同,参数列表不同的方法构成重载。


可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。


可变个数形参在方法的形参中,必须声明在末尾。


因此可变个数形参在方法的形参中,最多只能声明一个。


public class MethodVarArgsTest {


    public static void main(String[] args) {

        MethodVarArgsTest test = new MethodVarArgsTest();

        test.show(10);      // 重载方法1

        test.show("hello"); // 重载方法2

        test.show("hello","abcdef","12345"); // 可变个数形参方法

        test.show(); // 没有参数也可以调用可变形参方法

    }


    // 重载方法

    public  void show(int i){

        System.out.println("重载方法1");

    }


    public void show(String s) {

        System.out.println("重载方法2");

    }


    public void show(String ... str) {

        System.out.println("可变个数形参方法");

        // 使用时,把可变个数形参当作数组使用

        for(int i = 0; i < str.length;i++) {

            System.out.println(str[i]);  // 当作数组用

        }

    } 

    

    // 相同类型的数组会与可变类型方法 不能构成重载,会发生冲突。

    /*public void show(String[] strs) {

        

    }*/

    

    // 正确写法,必须声明在末尾

    public void show(int i, String ... str) {


    } 

    

    // 错误写法! Vararg parameter must be the last in the list

    /*public void show(String ... str, int i) {

        

    }*/

    

    

}

Java开发入门到精通 -- 面向对象概述与封装性



方法参数的值传递机制

在Java中方法的参数传递方式只有一种**值传递**,即将实际参数值的副本传入方法内,而参数本身不受影响。


形参是基本数据类型:将实参基本数据类型变量的**数据值**传给形参。

形参是引用数据类型:将实参引用数据类型变量的**地址值**传给形参。

练习

练习1

下面代码的输出结果是?


class Value {

    int i = 15;

}


public class TransferTest3 {

    public static void main(String args[]) {

        TransferTest3 test = new TransferTest3();

        test.first();   

    }

    

    public void first() {

        int i = 5;  

        Value v = new Value();

        v.i = 25;     

        second(v,i);   

        System.out.println(v.i);  // 20 【传递的是地址值】

    }

    public void second(Value v,int i) {

        // v = 25, i = 5

        i = 0;  // i = 0

        v.i = 20;  // v = 25

        Value val = new Value();

        v = val;  // v = 15

        System.out.println(v.i+" " + i); // 15 0

    }

}



练习2

// 下面代码的输出结果

public class ArrayPrintTest {

    int[] arr = new int[]{1,2,3};

    System.out.println(arr); // 地址值

    

    char[] arr1 = new char[]{'a','b','c'};

    System.out.println(arr1); // abc

    // println(char[]) 的重载方法,会遍历该char[] 并打印

}


递归方法

方法递归(recursion)包含了一种隐式的循环,它会重复执行某段代码,但是这种重复执行无须序循环控制。


递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。


/**

 * 递归方法的使用

 */

public class Demo01Recursion {

    public static void main(String[] args) {

        // 递归计算1-100所有自然数的和

        int n = 100;

        int sum =  getSum(n);

        System.out.println(sum);


        // 递归计算n!

        System.out.println(getFact(10));


        // 已知有一个数列 f(0) = 1, f(1) = 4, f(n+2) = 2 * f(n+1) + f(n), 求f(10) 的值

        // f(n + 2) = 2 * f(n + 1) + f(n);

        // f(10) = 2 * f(9) + f(8)

        // f(n) = 2 * f(n - 1) + f(n - 2);

        System.out.println(f(10));


        // 求第n个斐波那契数

        System.out.println(Fib(10));


    }

    //  求和

    public static int getSum(int n){

        if(n >= 1){

            return n + getSum(n-1);

        }

        return 0;

    }

    // 求阶乘

    public static int getFact(int n){

        return n == 1? 1 : n * getFact(n-1);

    }


    // 求f(n)

    public static int f(int n){

        if(n == 0){

            return 1;

        } else if(n == 1) {

            return 4;

        } else {


            return  2 * f(n - 1) + f(n - 2);

        }

    }


    // Fibonacci

    public static int Fib(int n){

        return n <= 2 ? 1 : Fib(n - 1) + Fib(n - 2);

    }


}


三大特征之封装

面向对象三大特征:封装、继承、多态。


封装概述

概述

面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。


封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。


程序设计追求:高内聚、低耦合。


高内聚:类的内部数据操作细节自己完成,不允许外部干涉;

低耦合:仅对外暴露少量的方法用于使用。

原则

将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。


体现

方法就是一种封装。

关键字private也是一种封装。

public class Demo02Method {

    public static void main(String[] args) {

        int[] arr= {1,2,3,4,5};

        int max = getMax(arr);

        System.out.println("最大值" + max);

    }

    public static int getMax(int[] arr){

        int max = arr[0];

        for (int i = 1; i < arr.length; i++) {

            max = arr[i] > max ? arr[i] : max;

         }

        return max;

    }

}

// 方法的调用者并不关心如何getMax()中的实现细节,它只是调用getMax()来完成获取数组最大值的功能。

// 将方法封装起来,就是隐藏细节,对外界不可见。


private关键字

private关键字用于修饰需要被保护的成员变量。


使用说明

// 创建一个Person 类

public class Person {

    String name;

    int age;

    

    public void show(){

        System.out.println("My name is " + name + ". I'm " + age + " years old");

    }

}


// 在main方法中创建一个Person对象

public class Demo03Person {

    public static void main(String[] args) {

        Person person = new Person();


        // 对对象中的成员变量进行赋值

        person.name = "Joker";

        person.age = -18; // -18 不合理的数值,成员变量无法阻止这个不合法的数据被设置。

        person.show();

        // private就是用来保护成员变量被赋予这种不合理数值的。

    }

}


private关键字用来修饰成员变量,被修饰的成员变量,在本类中可以随意访问,但是超出本类范围之外就不能在直接访问。


// 用private修饰 成员变量 age

public class Person {

    String name;

    private int age; 

    // 此时age 不能直接通过 对象名.成员变量名来访问

    public void show(){

        System.out.println("My name is " + name + ". I'm " + age + " years old");

    }

}

Java开发入门到精通 -- 面向对象概述与封装性



如果想要访问private修饰的成员变量,就需要使用间接访问的方法。


间接访问

间接访问private修饰的成员变量,就是在本类中定义一对**Getter/Setter方法**。


public class Person {

    String name;

    private int age;

    public void show(){

        System.out.println("My name is " + name + ". I'm " + age + " years old");

    }


    // Setter方法,专门用于设置age的数据

    public void setAge(int num){

        // 在Setter方法中加入判断条件,可以有效杜绝成员变量被赋予不合理的值。

        if(num <= 150="" num="">= 0){

            age = num;

        } else{

            System.out.println("Error,the date of num is corrputed!");

        }

    }

    // Getter方法,专门用获取age的数据

    public int getAge() {

        return age;

    }

}


public class Demo03Person {

    public static void main(String[] args) {

        Person person = new Person();


        person.name = "Joker";

//        person.age = 18; // 此时需要访问age变量就不能使用直接访问的方法

        person.setAge(18); // 而是使用间接访问的方法,并将想赋予的值写在方法调用()中

        person.show();

        int JokerAge = person.getAge();  // 获取成员变量的值,也应该使用间接访问方法

        System.out.println("Joker's age is " + JokerAge);

    }

}

Java开发入门到精通 -- 面向对象概述与封装性



Setter方法

public void setXxx(para) {

    // 方法体

}


Setter方法必须有参数,无返回值;参数类型与要被设置的成员变量保持一致。


命名规则:set + 变量名首字母大写。


Getter方法

public dataType getXxx() {

    // 方法体

}


Getter方法必须有返回值,无参数,返回值类型与要设置的成员变量保存一致。


命名规则:get + 变量名首字母大写。


练习

利用primate关键字定义一个学生类


// 利用primate关键字定义一个学生类

public class Student {

    private String name;  // 姓名

    private short age;

    private boolean male;  // true为男,false 为女

    

    public void setName(String str){

        name = str;

    }


    public String getName(){

        return name;

    }


    public void setAge(short num){

        age = num;

    }

    public short getAge() {

        return age;

    }

    

    public void setMale(boolean b){

        male = b;

    }

    

    // boolean的Getter方法命名 应该是 isXxxx

    public boolean isMale() {

        return male;

    }

}


注意:


基本数据类型中的boolean值,其Getter方法的命名一定要写成**isXxxx**


// 使用学生类创建对象

public class Demo04Student {

    public static void main(String[] args) {

        Student stu = new Student();


        stu.setName("张三");

        stu.setAge(18);

        stu.setMale(true);


        System.out.println("姓名:" + stu.getName());

        System.out.println("年龄:" + stu.getAge());

        String sex = stu.isMale()? "男" : "女";

        System.out.println("性别:" + sex);

    }

}

Java开发入门到精通 -- 面向对象概述与封装性



this关键字

当成员方法中的局部变量,和成员变量重名时,根据"就近原则",优先使用局部变量。


// 定义Person类

public class Person {


    String name; // 成员变量

    

    // 成员方法的局部变量名和成员变量名都是name

    public void sayHello(String name){ // 局部变量

        System.out.println(name + ",您好!我是" + name);

    }

}


// 使用Person类创建对象

public class Demo01Person {

    public static void main(String[] args) {

        Person person = new Person();

        person.name = "张三";

        person.sayHello("罗翔老师");

    }

}

// 结果是成员方法优先使用的是局部变量name

Java开发入门到精通 -- 面向对象概述与封装性



解决方法是使用this关键字。


public class Person {

    String name; // 姓名

    

    public void sayHello(String name){

        System.out.println(name + ",您好!我是" + this.name);

    }

}

// this.name 就相当于 person.name

Java开发入门到精通 -- 面向对象概述与封装性



谁调用的方法,this就指向谁。

public class Person {

    String name; // 姓名


    public void sayHello(String name){

        System.out.println(name + ",您好!我是" + this.name);

        System.out.println(this); // 在成员方法中打印调用者的地址。

    }

}


public class Demo01Person {

    public static void main(String[] args) {

        Person person = new Person();

        person.name = "张三";

        person.sayHello("罗翔老师");

        System.out.println(person);  // 打印对象名


// 创建不同的对象

        System.out.println("========================");

        Person person1 = new Person();

        person1.name = "李四";   

        person1.sayHello("罗翔老师");   

        System.out.println(person1); // 打印对象名

    }

}

Java开发入门到精通 -- 面向对象概述与封装性


this 调用构造器

在类的构造器中,可以显式的使用this(形参列表)的方式,调用本类中指定的其他构造器。

构造器中不能通过this(形参列表)的方式来自己调用自己。

同时构造器之间不可以构成环形调用关系,如果一个类中有n个构造器,则最多有n-1个构造器中可以使用this(形参列表);

规定:this(形参列表)必须声明在当前构造器的首行,也就是构造器内部最多只能声明一个this(形参列表)。

补充(了解):如果没有显式的在构造器中指定调用哪一个构造器,那么默认会调用super(),用来在子类实例化时先加载父类的结构。

构造器

构造器(constructor)是专门用来创建对象的一种结构,当一个对象被创建时候,构造器用来初始化该对象,给对象的成员变量赋初始值。当我们通过关键new来创建对象时,其实就是在调用构造器。


tips:无论你与否自定义构造器,所有的类都有构造器,因为Java自动提供了一个空参构造器,一旦自己定义了构造器,Java自动提供的默认无参数构造器就会失效。


构造器的定义格式

修饰符 构造器名(参数类型 参数名称,...){

     // 方法体

}

// 构造器名与所在类名称完全一样!


注意事项

构造器的名称必须和所在的类名称完全一样,包括大小写也要一样。

构造器没有返回值类型,包括void。

构造器不能return一个具体的返回值。

如果没有自定义构造器,编译器会自动提供一个无参数构造器,格式如下:

public className() {} // 编译器默认提供的构造器


一旦定义了至少一个构造器,编译器提供的构造器将失效。

构造器可以进行重载,方法名相同,参数列表不同

// 定义一个类,在其中定义构造器

public class Student {

    // 成员变量

    String name;

    int age;



    // 构造器可以重载

    // 无参构造器

    public Student() { // 名字和类名完全一样

        System.out.println("无参构造器执行!");

    }


    // 全参构造器

    public Student(String name, int age) {

        System.out.println("全参构造器执行!");

        this.name = name;

        this.age = age;


    }


    // Setter/Getter 方法

    public void setName(String name)

    {

        this.name = name;

    }

    public String getName()

    {

        return name;

    }


    public void setAge(int age){

        this.age = age;

    }

    public int getAge(){

        return age;

    }

}


// 使用类

public class Demo02Student {


    public static void main(String[] args) {

         // 构造器的调用通过new className();

         Student stu = new Student();           // 调用无参构造器,方法重载

        

System.out.println("=============================");


         Student stu1 = new Student("张三",18); // 调用有参构造器,并进行初始化,方法重载

         System.out.println("姓名:" + stu1.getName() + " 年龄:" + stu1.age);


         System.out.println("=============================");

        

         // Setter方法用来对成员变量重新赋值

         stu1.setName("法外狂徒");   

         stu1.setAge(19);

         System.out.println("姓名:" + stu1.getName() + " 年龄:" + stu1.age);


    }

}

Java开发入门到精通 -- 面向对象概述与封装性



标准代码——JavaBean

一个标准的类同时需要拥有下面四个组成部分:


所有的成员变量都要使用**private**关键字修饰。

为每一个成员编写一对**Getter/Setter**方法。

编写一个无参数的构造器。

编写一个全参数的构造器

这样一个标准的类也被称为 Java Bean


public class ClassName{

//成员变量

//构造器

//无参构造器【必须】

//有参构造器【建议】

//成员方法

//getXxx()

//setXxx()

}


举例

// 定义一个标准的学生类

public class Student {

    // 成员变量

    private String name; // 姓名

    private int age;     // 年龄


    // 自动生成的无参构造器

    public Student() {

    }


    // 自动生成的全参构造器

    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }


    

    // 自动生成的Getter / Setter

    public String getName() {

        return name;

    }


    public void setName(String name) {

        this.name = name;

    }


    public int getAge() {

        return age;

    }


    public void setAge(int age) {

        this.age = age;

    }

}


//使用类

public class Demo01Student {

    public static void main(String[] args){


        Student stu1 = new Student();   // 调用无参构造器

        stu1.setName("张三");           // 使用Setter方法赋值

        stu1.setAge(18);

        // 使用Getter方法获取值

        System.out.println("姓名:" + stu1.getName() + ",年龄:" + stu1.getAge());


        System.out.println("====================");


        Student stu2 = new Student("李四",19); // 调用全参构造器

        System.out.println("姓名:" + stu2.getName() + ",年龄:" + stu2.getAge());


        System.out.println("====================");


        stu1.setName("法外狂徒");                          // Setter方法修改值

        stu1.setAge(99);

        System.out.println("姓名:" + stu1.getName() + ",年龄:" + stu1.getAge());

    }

}


static

static主要修饰类的内部结构:属性、方法、代码块、内部类。


被static修饰的内部结构,会随着类的加载而加载。


修饰属性

static修饰的属性,称作静态变量。


随着类的加载而加载。

在程序运行期间只会被加载一次。

属于类不属于对象。(权限运行,对象可以调用)

存在于方法的静态域中。

使用场景

当该属性可以被多个对象共享时。例如: 国籍、教室等公共的属性。

类中的常量,经常被static修饰。

static内存图

Java开发入门到精通 -- 面向对象概述与封装性


修饰方法

static修饰的方法,被称作静态方法。


随着类的加载而加载。

静态方法中,只能调用静态的方法或属性。

非静态方法中,既可以调用静态的方法或属性、也可以调用非静态的方法或属性。

在静态的方法内,不能使用this和super关键字。

使用场景

方法中如果需要操作静态属性,同常设置为静态方法。

工具类中的方法,习惯上声明为static的。比如:Math、Arrays、Collections

修饰代码块

staitc修饰的代码块称为静态代码块。


静态代码块

内部可以有输出语句。

随着类的加载而执行。

只会在类加载的时候,执行唯一一次。

如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行。

静态代码块内只能调用静态的属性。静态的方法,不能调用非静态的结构。

作用:初始化静态属性。


我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取基础课程·答疑解惑·职业测评

Java开发入门到精通 -- 面向对象概述与封装性

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程