封装性

image.png

信息的封装和隐藏

image.png

  1. class Animal {
  2. private int legs;// 将属性legs定义为private,只能被Animal类内部访问
  3. public void setLegs(int i) { // 在这里定义方法 eat() 和 move()
  4. if (i != 0 && i != 2 && i != 4) {
  5. System.out.println("Wrong number of legs!");
  6. return;
  7. }
  8. legs = i;
  9. }
  10. public int getLegs() {
  11. return legs;
  12. }
  13. }
  14. public class Zoo {
  15. public static void main(String args[]) {
  16. Animal xb = new Animal();
  17. xb.setLegs(4); // xb.setLegs(-1000);
  18. //xb.legs = -1000; // 非法
  19. System.out.println(xb.getLegs());
  20. }
  21. }

权限修饰符

image.png


继承性

  • 个人感觉继承的关键字extends挺形象的,翻译成“扩展”,这样就不会迷谁继承谁,谁是子集谁是父集。
  • IntelliJIDEA 查看子父类关系快捷键:ctrl+H

image.png
image.png
image.png
image.png
image.png

子类对象的实例化全过程

  1. 从结果上来看:(继承性)
  • 子类继承父类以后,就获取了父类中声明的属性或方法。
  • 创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
  1. 从过程上来看:
  • 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,…直到调用java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。

明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。


多态性

个人理解:有的时候你不清楚具体要用什么子类,就先写成父类,具体情况再用子类代替(编译用父类,运行用子类),提高了代码的通用性

image.png
image.png
image.png
编译期只能调用父类中声明的方法,运行期执行的是子类重写父类的方法,不能调用子类特有的方法(编译看左边,运行看右边)属性(编译和运行都看左边)

虚拟方法调用

多态是运行时行为,编译时先用父类方法,运行时再动态调用属于子类的该方法。

image.png

对象类型转换

image.png

向上转型(子->父)

多态

向下转型(父->子)

向下转型:为了调用子类特有的属性和方法

有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用。
如何才能调用子类特有的属性和方法? -> 向下转型:使用强制类型转换符。

Person p1=new Man();
Man m1=(Man)p1;

使用强转时,可能出现ClassCastException的异常。

Woman w1 = (Woman)p2;
w1. goShopping();

利用instanceof,在向下转型前可以先判断:
image.png

Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型:
    Student s = (Student) p; // 一定会成功
}