JAVA-继承和多态

1.继承和多态概述

  1. 面向对象编程的三大支柱: 封装,继承,多态
  2. 继承:面向对象编程支持从已经存在的类中定义新的类.
  3. 多态意外着父类型的变量可以引用子类型的变量.

2.继承

2.1父类和子类

  1. 若类c1继承自另一个类c2,则有:c1:子类(继承类,派生类); c2:超类(父类,基类)
  2. 子类从父类中继承可访问的数据域和方法,还可以添加新得数据域和方法.

注意事项:

  1. 子类并不是父类的一个子集,子类一般比父类包含更多的信息和方法.
  2. 父类中的私有数据域在该类外是不可访问的,不能在子类中直接使用.但可使用公共的修改/访问器来对其进行操作.
  3. 不是所有is-a关系都可以用继承建模.(正方形不应该继承矩形,因为其不适于用长,宽属性,其应该继承于Geom...类)
  4. Java不允许多重继承(几个类派生出一个子类),但可通过接口来实现.

2.2extends

  • 关键词extends告诉编译器A继承自B类,则A可以用B的数据域以及方法

    public class A extends B{}

2.3super

  • 关键字super指代父类,可以用于调用父类中的普通方法和构造方法.
  1. 调用父类的构造方法: super()/super(arguments);
    若要调用父类的构造方法,必须使用super关键字且置于构造方法的第一条语句.
  2. 构造方法链:任何情况下,构造一个类的实例时将会调用沿着继承链的所有父类的构造方法.
    1. 构造一个子类的对象时,子类的构造方法会在完成自己的任务之前,首先调用它的父类的构造方法,...持续到最后一个构造方法被调用为止.
    2. 构造方法可以调用重载的构造方法或父类的构造方法.若它们都没有被显式地调用,编译器会自动将super()作为构造方法的第一条语句.
  3. 若要设计一个可被继承的类,最好提供一个无参构造方法以避免错误(最好为每个类提供一个无参构造方法)
  4. 调用父类的普通方法: super.方法名(argument);

3.多态

3.1方法重写和重载比较

  • 重载: 使用同样的名字但是不同的签名来定义多个方法.
  • 重写: 在子类中提供一个对方法的新的实现.
  1. 方法重写发生在具有继承关系的不同类中;方法重载可以发生在同一个类中,也可以发生在具有继承关系的不同类中.
  2. 方法重写具有同样的签名;方法重载具有同样的名字但是不同的参数列表.
    为避免错误,可使用重写标注:在子类的方法前放一个@Override,该标注表示被标注的方法必须重写父类的一个方法.

eg.

public class A extends B{
	@Override
	public String toString(){
		return super.toString() + "wow!";
	}
}

3.2重载式多态(编译时多态,静态)

这种多态在编译时已经确定好了,在调用这种重载的方法时,通过传入不同的参数最后得到不同的结果。

3.3重写时多态(运行时多态,动态)

这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

三个必要条件:继承(实现)、重写和向上转型

3.3.1向上转型

  • 子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口。

示例:
Animal animal = new Cat(); 将子类对象 Cat 转化为父类对象 Animal。这个时候 animal 这个引用调用的方法是子类方法。

  1. 向上转型时,子类单独定义的方法会丢失。比如上面Dog类中定义的run方法,当animal引用指向Dog类实例时是访问不到run方法的,animal.run()会报错。
  2. 子类引用不能指向父类对象。Cat c = (Cat)new Animal()这样是不行的。
  3. 使用向上转型可以减少重复代码,使代码变得更简洁。且可提高系统的扩展性。

3.3.2向下转型

  1. 向下转型的前提是父类对象指向的是子类对象(在向下转型之前,它得先向上转型)
  2. 向下转型只能转型为本类对象(猫是不能变成狗的)。(可用关键字instanceof判断)

if(animal instanceof Cat) 若animal为Cat的实例,则返回true,可以向下转换:
Cat b = (Cat) animal;

3.3.3动态绑定

  • 动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。程序运行过程中,把函数(或过程)调用与响应调用所需要的代码相结合的过程称为动态绑定。
  • 方法可以沿着继承链的多个类实现,JVM决定运行时调用哪个方法.

eg.

Object o = new A();
o.toString();
  1. 声明类型(Object):一个变量必须被声明为某种类型.
    Object为o的声明类型
  2. 实际类型(A):被变量引用的对象的实际类.
    A为o的实际类型
  3. 动态绑定: o调用哪个toString()方法是由o的实际类型决定的.
  4. 工作机制:
    假设对象o是类c1,c2,...,cn的实例,其中c1是c2的子类,...,cn-1是cn的子类.
    若o调用了一个方法p,则JVM会依次在c1,c2,...,cn中查找方法p的实现直至找到.
    最终调用这个首先找到的实现.(一般而言,cn即为Object类)

4.Object类

4.1概述

  • Java的所有类都继承自java.lang.Object类

4.2 toString()方法

调用一个对象的toString()默认会返回一个描述该对象的字符串:
类名,at符号(@),使用十六进制形式表示的该对象在内存地址组成的字符串

4.3 Object类中的equals方法

  1. 同toString()方法,equals(Object)为Object类中另一个有用的方法
  2. 判断两个引用变量是否指向同一个对象(==)
  3. 经常用来重写以赋予其新的含义
posted @ 2021-07-28 18:55  rttrti  阅读(167)  评论(0)    收藏  举报