动态绑定机制

1.调用方法的时候,该方法会和该对象的 内存地址/运行类型 绑定

2.调用对象属性的时候,没有动态绑定机制,哪里申明,哪里使用.

  1. package com.hspedu.poly_.dynamic_;
  2. public class DynamicBinding {
  3. public static void main(String[] args) {
  4. //a 的编译类型 A, 运行类型 B
  5. A a = new B();//向上转型
  6. System.out.println(a.sum());//?40 -> 30
  7. System.out.println(a.sum1());//?30-> 20
  8. }
  9. }
  10. class A {//父类
  11. public int i = 10;
  12. //动态绑定机制:
  13. public int sum() {//父类 sum()
  14. return getI() + 10;//20 + 10
  15. 韩顺平循序渐进学 Java 零基础
  16. 333
  17. }
  18. public int sum1() {//父类 sum1()
  19. return i + 10;//10 + 10
  20. }
  21. public int getI() {//父类 getI
  22. return i;
  23. }
  24. }
  25. class B extends A {//子类
  26. public int i = 20;
  27. // public int sum() {
  28. // return i + 20;
  29. // }
  30. public int getI() {//子类 getI()
  31. return i;
  32. }
  33. // public int sum1() {
  34. // return i + 10;
  35. // }
  36. }

方法重写

也叫方法覆盖

  1. 子类的方法的形参列表,方法名称,要和父类方法的形参列表,方法名称一样

  2. 子类方法的返回值类型和父类方法返回值类型一样,或者是父类返回值类型的子类
    比如父类返回类型是Object,子类方法返回类型是String

  3. 子类方法不能缩小父类方法的访问权限 public > protected > 默认 > private

方法的重写规则

  • 参数列表与被重写方法的参数列表必须完全相同。
  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为 final 的方法不能被重写。
  • 声明为 static 的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个类,则不能重写该类的方法。

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

继承

java子类和父类有相同成员_Java — 父类和子类拥有同名的成员变量的情况

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

需要注意的是 Java 不支持多继承,但支持多重继承。

第8章 多态 - 图1

继承的特性

  • 子类拥有父类非 private 的属性、方法。

  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法。

  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

  • 当子类的成员变量与父类同名时,若对该成员变量进行操作的方法继承于父类,则改变和获取的是父类的成员变量。若对该成员变量进行操作的方法为子类所独有,或override父类,则改变和获取的是子类自己的成员变量。
    当子类拥有与父类同名的成员变量时,父类的成员变量并不会被覆盖,而是与子类的成员变量分别存储在不同的空间,其值仍然可以被改变和访问。

继承关键字

extends关键字

在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

  • 声明类:
    1. final class 类名 {//类体}
  • 声明方法:
    1. 修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final

多态的体现

1.方法多态

  1. (1) 重载体现多态
  2. (2) 重写体现多态

2.对象多态

  1. (1) 对象的编译类型和运行类型可以不一致,编译类型在定义时,就确定,不能变化
  2. (2) 对象的运行类型是可以变化的,可以通过 getClass() 来查看运行类型
  3. (3) 编译类型看定义时候 = 号的左边,运行类型看 = 号的右边

成员变量:

  1. 编译看左边,运行看左边

成员方法:

  1. 编译看左边,运行看右边

静态方法:

  1. 编译看左边,运行看左边(静态和类相关,算不上重写)

获取对象的运行类型的方法:

  1. 对象名.getclass();

向上转型

本质:父类的引用指向子类的对象

语法:父类类型 引用名 = new 子类类型();

特点:编译类型看左边,运行类型看右边.

可以调用父类中的所有成员(需遵守访问权限),

不能调用子类中的成员;

向下转型和类型判断

语法: 子类类型 引用名 = (子类类型) 父类引用;

只能强转父类的引用,不能强转父类对象

要求父类的引用必须指向的是当前目标类型的对象

向下转型后,可以调用子类类型中所有的成员

属性没有重写一说!属性的值看编译类型.

instanceOf(用于类型判断)

比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类

如果只是用父类的对象不能调用子类的方法,需要向下转型

向下转型实例:

  1. if(persons[i] instanceof Student){
  2. Student student = (Student)persons[i];
  3. student.study();
  4. //也可以使用一条语句 ((Student)persons[i]).study();
  5. }else if(persons[i] instanceof Teacher){
  6. Teacher teacher = (Teacher)persons[i];
  7. teacher.teach();
  8. }else{
  9. system.out.println("代码运行有误..请仔细检查");
  10. }