封装
该露的露,该藏的藏
我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
记住这句话:属性私有,get/set
封装的作用:
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性增加了
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.xiheya.oop.demo04;public class Student { private String name; private int id; private char sex; public Student () { } public Student (String name, int id, char sex) { this .name = name; this .id = id; this .sex = sex; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getId () { return id; } public void setId (int id) { this .id = id; } public char getSex () { return sex; } public void setSex (char sex) { this .sex = sex; } }
运行结果:
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends 的意思是”扩展“。子类是父类的扩展。
Java中类只有单继承,没有多继承!
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类)、一个为父类(基类)。子类继承父类,使用关键字extends来表示。
object类
super
方法重写
子类继承了父类,就会拥有父类的全部方法,前提是方法属性为 在Java中所有类都默认直接或间接继承Object;快捷键:ctrl+H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.xiheya.oop.demo05;public class Person { public void speak () { System.out.println("say some thing" ); } }
可以看到Teacher类没有speak方法,但是实例化的teacher对象却可以调用speak方法,原因就是Teacher继承了Person类,而Person类中定义了speak方法。
super关键字: super关键字可以在子类调用父类。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package com.xiheya.oop.demo05;public class Person { public Person () { System.out.println("Person类的构造方法执行了" ); } public void speak () { System.out.println("say some thing" ); } public void print () { System.out.println("Person" ); } }
运行结果:
可以看到,当对象被实例化之后,会调用构造器方法,如果有父类则先调用父类的构造器方法。这是因为子类的构造方法中:默认添加了super();关键字,所以会先调用父类的构造器方法!同时,调用父类的构造器必须放在第一行。
super注意点
super调用父类的构造方法,必须在构造方法的第一个
super必须只能出现在子类的方法或者构造方法中
super和this不能同时调用构造方法
super与this的区别
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法:
this();本类的构造
super():父类的构造
方法重写 静态方法是类的方法,而非静态方法是对象的方法。 有static时,对象调用的是自身类的方法,没有static时,对象调用的是自身对象的方法。
静态方法和非静态方法差别很大
静态方法:方法的调用只和左边定义的数据类型有关
非静态:非静态方法才存在重写。
只有非静态的 public属性的方法才能被重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.xiheya.oop.demo05;public class B { public void test () { System.out.println("b--->test" ); } }
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.xiheya.oop.demo05;public class B { public void test () { System.out.println("b--->test" ); } }
运行结果
笔记 重写:需要有继承关系,子类重写父类的方法!
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大. public>protected>default>private
抛出的异常:范围可以被缩小,但不能扩大。eg父类抛出的异常为:Exception,那么子类抛出的异常范围就需要比Exception要小。可以抛出为:ClassNotFoundException
重写:子类的方法和父类必须要一致,方法体不同。
为什么要重写 :
父类的功能,子类不一定需要,或者不一定满足
多态
动态编译:类型”可扩展性更强
多态即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
多态存在的条件
有继承关系
子类重写父类方法
父类引用指向子类对象
注意:多态是方法的多态,属性没有多态
instanceof
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package com.xiheya.oop.demo06;public class Person { public void run () { System.out.println("Person run" ); } }
运行结果
注意事项
多态是方法的多态;属性没有多态。
父类和子类,有联系 (类型转换异常–ClassCastException)
存在条件:继承关系,方法需要重写,父类引用指向子类对象。Father f1 = new Son();
哪些方法不能重写?
static方法,static代码块属于类,对象被创建时一同被执行
final:常量 被final修饰的方法不能被重写,被final修饰的类不能被继承;被final修饰的变量一经赋值后续不能更改。
private方法: 私有属性不能被继承
instanceof关键字 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package com.xiheya.oop;import com.xiheya.oop.demo06.Teacher;import com.xiheya.oop.demo06.Student;import com.xiheya.oop.demo06.Person;public class Application { public static void main (String[] args) { Student student = new Student (); Person person = new Student (); Object object = new Student (); System.out.println(object instanceof Student); System.out.println(object instanceof Person); System.out.println(object instanceof Object); System.out.println(object instanceof Teacher); System.out.println(object instanceof String); System.out.println("========================" ); System.out.println(person instanceof Student); System.out.println(person instanceof Person); System.out.println(person instanceof Object); System.out.println(person instanceof Teacher); System.out.println("========================" ); System.out.println(student instanceof Student); System.out.println(student instanceof Person); System.out.println(student instanceof Object); } }
运行结果
强制转换
父类引用指向子类的对象
把子类转换为父类:向上转型:(自动转换)
把父类转换为子类:向下转型:(强制转换)
方便方法的调用,减少代码重复率,简洁
由Student类型转换为他的父类Person类型可以直接转换,但是可能会丢失一些自己本来的方法。
student.go();报错: 因为Person类中没有go方法。需要将Person类型强制转换为Student类型
类型之间的转换 高——————-低(强制转换)
低——————-高(自动转换)
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Application { public static void main (String[] args) { Person obj = new Student (); ((Student) obj).go(); Student student = new Student (); Person person = student; } }