博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java笔记(04):面向对象--封装
阅读量:5020 次
发布时间:2019-06-12

本文共 18200 字,大约阅读时间需要 60 分钟。

1、面向对象的简单说明

1 /* 2     事物: 3     属性    事物的信息描述 4     行为    事物的功能 5  6     类: 7     成员变量    事物的属性 8     成员方法    事物的行为 9     10     定义一个类,其实就是定义该类的成员变量和成员方法。11 12     手机事物:13         属性:品牌,价格,颜色...14         行为:打电话,发短信,玩游戏...15         16     手机类:17         成员变量:品牌,价格,颜色18         成员方法:打电话,发短信,玩游戏19         20     成员变量:和以前变量的定义是一样的格式,但是位置不同,在类中方法外。21     成员方法:和以前的方法定义是一样的格式,但是今天把static先去掉。22 */23 class Phone {24     //品牌25     String brand;26     //价格27     int price;28     //颜色29     String color;30     31     //打电话的方法32     public void call(String name) {33         System.out.println("给"+name+"打电话");34     }35     36     //发短信的方法37     public void sendMessage() {38         System.out.println("群发短信");39     }40     41     //玩游戏的方法42     public void playGame() {43         System.out.println("玩游戏");44     }45 }

一个对象的内存分布:

两个对象的内存分部:

三个对象的内存分部:

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

1 /* 2     成员变量和局部变量的区别? 3         A:在类中的位置不同 4             成员变量:在类中方法外 5             局部变量:在方法定义中或者方法声明上 6         B:在内存中的位置不同 7             成员变量:在堆内存 8             局部变量:在栈内存 9         C:生命周期不同10             成员变量:随着对象的创建而存在,随着对象的消失而消失11             局部变量:随着方法的调用而存在,随着方法的调用完毕而消失12         D:初始化值不同13             成员变量:有默认初始化值14             局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。15             16         注意事项:17             局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。18 */19 class Varialbe {20     //成员变量21     //int num = 10;22     int num; //023     24     public void show() {25         //int num2 = 20; //局部变量26         //可能尚未初始化变量num227         //int num2; //没有默认值28         int num2 = 20;29         System.out.println(num2);30         31         //int num = 100;32         System.out.println(num);33     }34 }35 36 37 class VariableDemo {38     public static void main(String[] args) {39         Varialbe v = new Varialbe();40         41         System.out.println(v.num); //访问成员变量42         43         v.show();    44             45     }46 }

3、形式参数是类名

1 /* 2     形式参数的问题: 3         基本类型:形式参数的改变不影响实际参数 4         引用类型:形式参数的改变直接影响实际参数 5 */ 6 //形式参数是基本类型 7 class Demo { 8     public int sum(int a,int b) { 9         return a + b;10     }11 }12 13 //形式参数是引用类型14 class Student {15     public void show() {16         System.out.println("我爱学习");17     }18 }19 20 class StudentDemo {21     //当一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。22     public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();23         s.show();24     }25 }26 27 class ArgsTest {28     public static void main(String[] args) {29         //形式参数是基本类型的调用30         Demo d = new Demo();31         int result = d.sum(10,20);32         System.out.println("result:"+result);33         System.out.println("--------------");34         35         //形式参数是引用类型的调用36         //需求:我要调用StudentDemo类中的method()方法37         StudentDemo sd = new StudentDemo();38         //创建学生对象39         Student s = new Student();40         sd.method(s); //把s的地址给到了这里41     }42 }

4、匿名对象

1 /* 2     匿名对象:就是没有名字的对象。 3      4     匿名对象的应用场景: 5         A:调用方法,仅仅只调用一次的时候。 6             注意:调用多次的时候,不适合。 7             那么,这种匿名调用有什么好处吗? 8                 有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。 9         B:匿名对象可以作为实际参数传递10 */11 class Student {12     public void show() {13         System.out.println("我爱学习");14     }15 }16 17 class StudentDemo {18     public void method(Student s) {19         s.show();20     }21 }22 23 class NoNameDemo {24     public static void main(String[] args) {25         //带名字的调用26         Student s = new Student();27         s.show();28         s.show();29         System.out.println("--------------");30         31         //匿名对象32         //new Student();33         //匿名对象调用方法34         new Student().show();35         new Student().show(); //这里其实是重新创建了一个新的对象36         System.out.println("--------------");37         38         39         //匿名对象作为实际参数传递40         StudentDemo sd = new StudentDemo();41         //Student ss = new Student();42         //sd.method(ss); //这里的s是一个实际参数43         //匿名对象44         sd.method(new Student());45         46         //在来一个47         new StudentDemo().method(new Student());48      }49 }

5、封装和private关键字

1 /* 2     private: 3         是一个权限修饰符 4         可以修饰成员变量和成员方法 5         被其修饰的成员只能在本类中被访问 6 */ 7 class Demo { 8     //int num = 10; 9     //用private修饰10     private int num = 10;11     12     public void show() {13         System.out.println(num);14     }15     16     private void method() {17         System.out.println("method");18     }19     20     public void function() {21         method();22     }23 }24 25 class PrivateDemo {26     public static void main(String[] args) {27         Demo d = new Demo();28         //不能方法私有的成员变量29         //System.out.println(d.num);30         d.show();31         //不能访问私有的成员方法32         //d.method();33         d.function();34     }35 }
1 /* 2     定义一个学生类: 3         成员变量:name,age 4         成员方法:show()方法 5          6     我们在使用这个案例的过程中,发现了一个问题: 7         通过对象去给成员变量赋值,可以赋值一些非法的数据。 8         这是不合理的。 9         应该是这个样子的:在赋值之前,先对数据进行判断。10         判断到底在哪里做比较合适呢?11         StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。    12         所以,这个判断应该定义在Student类中。13         而我们在成员变量的位置可不可以进行数据判断呢?14         是不可以的,因为做数据校验,必须要依靠一些逻辑语句。15         逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法16         来对数据进行校验。17     18     按照我们前面的分析,我们给出了一个方法进行校验。19     但是呢,它偏偏不调用方法来赋值,还是直接赋值了,20     这样我们的方法就没有起到作用。21     我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。22     怎么去强制要求不能直接使用成员变量呢?23         针对这种情况,Java就提供了一个关键字 private24         25     private:私有的。可以修饰成员变量和成员方法。26         注意:被private修饰的成员只能在本类中访问。27         28     其实我讲到现在讲解的是一个封装的思想。29     封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。30 */31 class Student {32     //姓名33     String name;34     //年龄35     private int age;36     37     //写一个方法对数据进行校验38     /*39         返回值类型:void40         参数列表:int a41     */42     public void setAge(int a) {43         if(a < 0 || age > 120) {44             System.out.println("你给的年龄有问题");45         }else {46             age = a;47         }48     }49     50     51     //show()方法,显示所有成员变量值52     public void show() {53         System.out.println("姓名:"+name);54         System.out.println("年龄:"+age);55     }56 }57 58 class StudentDemo {59     public static void main(String[] args) {60         //创建学生对象61         Student s = new Student();62         s.show();63         System.out.println("--------------");64         65         //给成员变量赋值66         s.name = "林青霞";67         //s.age = 27;68         s.setAge(27);69         s.show();70         System.out.println("--------------");71         72         //给age赋值73         //s.age = -27; //这个数据是不合理的74         //通过方法给值75         s.setAge(-27);76         s.show();77         System.out.println("--------------");78     }79 }
1 /* 2     封装和private的应用: 3         A:把成员变量用private修饰 4         B:提高对应的getXxx()和setXxx()方法 5 */ 6 //定义学生类 7 class Student { 8     //姓名 9     private String name;10     //年龄11     private int age;12     13     //姓名获取值14     public String getName() {15         return name;16     }17     18     //姓名设置值19     public void setName(String n) {20         name = n;21     }22     23     //年龄获取值24     public int getAge() {25         return age;26     }27     28     //年龄赋值29     public void setAge(int a) {30         age = a;31     }32 }33 34 //测试类35 class StudentTest {36     public static void main(String[] args) {37         //创建学生对象38         Student s = new Student();39         40         //使用成员变量41         //错误:被私有修饰了,外界不能直接访问了42         //System.out.println(s.name+"---"+s.age);43         System.out.println(s.getName()+"---"+s.getAge());44         45         //给成员变量赋值46         //s.name = "林青霞";47         //s.age = 27;48         //通过方法给赋值49         s.setName("林青霞");50         s.setAge(27);51         System.out.println(s.getName()+"---"+s.getAge());52     }53 }

6、this关键字

1 /* 2     我们曾经曰:起名字要做到见名知意。 3      4     this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。 5      6         注意:谁调用这个方法,在该方法内部的this就代表谁。 7          8     this的场景: 9         解决局部变量隐藏成员变量10 */11 //定义学生类12 class Student {13     //姓名14     private String name;15     //年龄16     private int age;17     18     //姓名获取值19     public String getName() {20         return name;21     }22     23     //姓名设置值24     public void setName(String name) { //name = "林青霞";25         //name = name; //变量的使用规则:就近原则26         //这里是类名,目前还没有说过类似的用法,所以这个是有问题的27         //这里的调用只能通过对象名28         //这个对象如果存在,它应该代表的是Student的一个对象。29         //那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this30         //Student.name = name;31         this.name = name;32     }33     34     //年龄获取值35     public int getAge() {36         return age;37     }38     39     //年龄赋值40     public void setAge(int age) {41         this.age = age;42     }43 }44 45 //测试类46 class StudentTest {47     public static void main(String[] args) {48         //创建学生对象49         Student s = new Student();50         51         //给成员变量赋值52         s.setName("林青霞");53         s.setAge(27);54         //获取数据55         System.out.println(s.getName()+"---"+s.getAge());56     }57 }
1 /* 2     标准的代码改进版 3      4     this:哪个对象调用那个方法,this就代表那个对象 5 */ 6 class Student { 7     private String name; 8     private int age; 9     10     public String getName() {11         return name; //这里其实是隐含了this12     }13     14     public void setName(String name) {15         this.name = name;16     }17     18     public int getAge() {19         return age;20     }21     22     public void setAge(int age) {23         this.age = age;24     }25 }26 27 class StudentTest2 {28     public static void main(String[] args) {29         //创建一个对象30         Student s1 = new Student();31         s1.setName("林青霞");32         s1.setAge(27);33         System.out.println(s1.getName()+"---"+s1.getAge());34         35         //创建第二个对象36         Student s2 = new Student();37         s2.setName("刘意");38         s2.setAge(30);39         System.out.println(s2.getName()+"---"+s2.getAge());40     }41 }

7、构造方法

1 /* 2     构造方法: 3         给对象的数据进行初始化 4  5     格式: 6         A:方法名与类名相同 7         B:没有返回值类型,连void都没有 8         C:没有具体的返回值 9 */10 class Student {11     private String name; //null12     private int age; //013     14     public Student() {15         System.out.println("这是构造方法");16     }17 }18 19 class ConstructDemo {20     public static void main(String[] args) {21         //创建对象22         Student s = new Student();23         System.out.println(s); //Student@e5bbd624     }25 }
1 /* 2     我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢? 3      4     构造方法的注意事项: 5         A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。 6         B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。 7             注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法 8          9     给成员变量赋值有两种方式:10         A:setXxx()11         B:构造方法12 */13 14 class Student {15     private String name;16     private int age;17 18     public Student() {19         //System.out.println("我给了,你还给不");20         System.out.println("这是无参构造方法");21     }22     23     //构造方法的重载格式24     public Student(String name) {25         System.out.println("这是带一个String类型的构造方法");26         this.name = name;27     }28     29     public Student(int age) {30         System.out.println("这是带一个int类型的构造方法");31         this.age = age;32     }33     34     public Student(String name,int age) {35         System.out.println("这是一个带多个参数的构造方法");36         this.name = name;37         this.age = age;38     }39     40     public void show() {41         System.out.println(name+"---"+age);42     }43 }44 45 class ConstructDemo2 {46     public static void main(String[] args) {47         //创建对象48         Student s = new Student();49         s.show();//null---050         System.out.println("-------------");51         52         //创建对象253         Student s2 = new Student("林青霞");54         s2.show();//林青霞---055         System.out.println("-------------");56         57         //创建对象358         Student s3 = new Student(27);59         s3.show();//null---2760         System.out.println("-------------");61         62         //创建对象463         Student s4 = new Student("林青霞",27);64         s4.show();//林青霞---2765     }66 }

8、成员方法

1 /* 2     类的组成:成员变量,成员方法 3     今天我们又加入了一个新的成员:构造方法。 4     以后再提类的组成: 5         成员变量 6         构造方法 7         成员方法 8             根据返回值: 9                 void类型10                 非void类型11             形式参数:12                 空参方法13                 非空参方法14 */15 class Student {16     public String getString() {17         return "helloworld";18     }19 20     public void show() {21         System.out.println("show");22     }23     24     public void method(String name) {25         System.out.println(name);26     }27     28     public String function(String s1,String s2) {29         return s1+s2;30     }31 }32 33 class StudentDemo {34     public static void main(String[] args) {35         //创建对象36         Student s = new Student();37         38         //调用无参无返回值方法39         s.show();40         41         //调用无参有返回值方法42         String result = s.getString();43         System.out.println(result);44         45         //调用带参无返回值的方法46         s.method("林青霞");47         48         //调用带参带返回值的方法49         String result2 = s.function("hello","world");50         System.out.println(result2);51     }52 }

9、创建对象做了哪些事情

10、练习

1 /* 2     定义一个类Demo,其中定义一个求两个数据和的方法, 3     定义一个测试了Test,进行测试。 4      5     变量什么时候定义为成员变量: 6         如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。 7          8     变量到底定义在哪里好呢? 9         变量的范围是越小越好。因为能及时的被回收。10 */11 12 //方式113 /*14 class Demo {15     public int sum() {16         int a = 10;17         int b = 20;18         int c = a + b;19         return c;20     }21 }22 */23 //方式1满足了我们的要求,但是不好。24 //因为参与操作的数据现在是固定的。25 26 //方式227 /*28 class Demo {29     public int sum(int a,int b) {30         return a + b;31     }32 }33 */34 35 //方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。36 //我就再想,a,b可不可以定义为成员变量呢?37 //如果可以,我们再改进一版38 class Demo {39     int a;40     int b;41     42     public int sum() {43         return a + b;44     }45 }46 //虽然这种方式可以,并且好像是符合了面向对象的思想。47 //但是不好。48 //因为我们曾经说过:类是一组相关的属性和行为的集合。49 //并且类是通过事物转换过来的50 //而类中的成员变量就是事物的属性51 //属性是用来描述事物的52 //同理:成员变量其实是用来描述类的。53 54 //测试类55 class Test {56     public static void main(String[] args) {57         //创建对象58         //方式1测试59         /*60         Demo d = new Demo();61         System.out.println(d.sum());62         */63         64         //方式2测试65         /*66         Demo d = new Demo();67         int a = 10;68         int b = 20;69         System.out.println(d.sum(a,b));70         */71         72         //方式3测试73         Demo d = new Demo();74         d.a = 10;75         d.b = 20;76         System.out.println(d.sum());77     }78 }

11、static关键字

1 /* 2     定义一个人类 3      4     姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。 5     但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。 6     一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间, 7     我就觉得有点浪费了。怎么办呢?  8         针对多个对象有共同的这样的成员变量值的时候, 9         Java就提高了一个关键字来修饰:static。10 */11 class Person {12     //姓名13     String name;14     //年龄15     int age;16     //国籍17     //String country;18     static String country;19     20     public Person(){}21     22     public Person(String name,int age) {23         this.name = name;24         this.age = age;25     }26     27     public Person(String name,int age,String country) {28         this.name = name;29         this.age = age;30         this.country = country;31     }32     33     public void show() {34         System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);35     }36 }37 38 class PersonDemo {39     public static void main(String[] args) {40         //创建对象141         Person p1 = new Person("邓丽君",16,"中国");42         p1.show();//姓名:邓丽君,年龄:16,国籍:中国43         44         //创建对象245         //Person p2 = new Person("杨幂",22,"中国");46         //p2.show();47         Person p2 = new Person("杨幂",22);48         p2.show();//姓名:杨幂,年龄:22,国籍:中国49         50         //创建对象351         //Person p3 = new Person("凤姐",20,"中国");52         //p3.show();53         Person p3 = new Person("凤姐",20);54         p3.show();//姓名:凤姐,年龄:20,国籍:中国55         56         p3.country = "美国";57         p3.show();//姓名:凤姐,年龄:20,国籍:美国58         59         p1.show();//姓名:邓丽君,年龄:16,国籍:美国60         p2.show();//姓名:杨幂,年龄:22,国籍:美国61     }62 }

static内存图解:

1 /* 2     static的特点:(它可以修饰成员变量,还可以修饰成员方法) 3         A:随着类的加载而加载 4             回想main方法。 5         B:优先于对象存在 6         C:被类的所有对象共享 7             举例:咱们班级的学生应该共用同一个班级编号。 8             其实这个特点也是在告诉我们什么时候使用静态? 9                 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。10             举例:11                 饮水机(用静态修饰)12                 水杯(不能用静态修饰)13         D:可以通过类名调用14             其实它本身也可以通过对象名调用。15             推荐使用类名调用。16             17             静态修饰的内容一般我们称其为:与类相关的,类成员18 */19 class Student {20     //非静态变量21     int num = 10;22     23     //静态变量24     static int num2 = 20;25 }26 27 class StudentDemo {28     public static void main(String[] args) {29         Student s = new Student();30         System.out.println(s.num);31         32         System.out.println(Student.num2);33         System.out.println(s.num2);34     }35 }
1 /* 2     static关键字注意事项 3         A:在静态方法中是没有this关键字的 4             如何理解呢? 5                 静态是随着类的加载而加载,this是随着对象的创建而存在。 6                 静态比对象先存在。 7         B:静态方法只能访问静态的成员变量和静态的成员方法 8                 静态方法: 9                     成员变量:只能访问静态变量10                     成员方法:只能访问静态成员方法11                 非静态方法:12                     成员变量:可以是静态的,也可以是非静态的13                     成员方法:可是是静态的成员方法,也可以是非静态的成员方法。14             简单记:15                 静态只能访问静态。16 */17 class Teacher {18     public int num = 10;19     public static int num2 = 20;20     21     public void show() {22         System.out.println(num); //隐含的告诉你访问的是成员变量23         System.out.println(this.num); //明确的告诉你访问的是成员变量24         System.out.println(num2);25         26         //function();27         //function2();28     }29     30     public static void method() {31         //无法从静态上下文中引用非静态 变量 num32         //System.out.println(num);33         System.out.println(num2);34         35         //无法从静态上下文中引用非静态 方法 function()36         //function();37         function2();38     }39     40     public void function() {41     42     }43     44     public static void function2() {45     46     }47 }48 49 class TeacherDemo {50     public static void main(String[] args) {51         //创建对象52         Teacher t = new Teacher();53         t.show();54         System.out.println("------------");55         t.method();56     }57 }

转载于:https://www.cnblogs.com/lz2lhy/p/6839056.html

你可能感兴趣的文章
Tkinter入门
查看>>
安卓AsyncTask异步下载图片
查看>>
求过圆心直线与圆的两个交点
查看>>
计蒜课中沙子的质量(动态规划)感想
查看>>
4.4 spring-自定义标签的解析
查看>>
zk配置文件详解
查看>>
ZPAY个人收款助手使用说明
查看>>
ubuntu vim之php函数提示
查看>>
FFT模板
查看>>
时间戳与时间类型转化(秒级时间戳)
查看>>
前端跨域解决方案
查看>>
FTP文件以网站形式解决FTP文件下载后才能观看使用
查看>>
判断是否有TrueType字体
查看>>
canvas显示黑色背景色问题
查看>>
过渡(显式动画)
查看>>
springboot 错误求解决
查看>>
PHP常见方法
查看>>
NPOI 列宽自适应 代码示例
查看>>
【终结篇】不要再问我程序员该如何提高了……
查看>>
iOS - Tools Using's Problem
查看>>