Java:面向对象--封装
Posted 花醉红尘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:面向对象--封装相关的知识,希望对你有一定的参考价值。
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; //0 23 24 public void show() { 25 //int num2 = 20; //局部变量 26 //可能尚未初始化变量num2 27 //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就提供了一个关键字 private 24 25 private:私有的。可以修饰成员变量和成员方法。 26 注意:被private修饰的成员只能在本类中访问。 27 28 其实我讲到现在讲解的是一个封装的思想。 29 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。 30 */ 31 class Student { 32 //姓名 33 String name; 34 //年龄 35 private int age; 36 37 //写一个方法对数据进行校验 38 /* 39 返回值类型:void 40 参数列表:int a 41 */ 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就提供了一个关键字 this 30 //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; //这里其实是隐含了this 12 } 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、构造方法