文章目录
1、多态的概念
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。多态是同一个行为具有多个不同表现形式或形态的能力。
多态的使用格式:父类类型 变量名=子类类型();
2、多态的实现方式
2.1重写
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。子类能够根据需要实现父类的方法,但重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
public class TestOverriding {
public static void main(String[] args) {
A a = new A();
a.p(10);
a.p(10.0);
}
}
class B{
public void p(double i) {
System.out.println(i * 2);
}
}
class A extends B{
@Override
public void p(double i) {
System.out.println(i);
}
}
2.2接口
java中的接口指的是抽象方法的集合,一个抽象类型,一般以interface来声明。需要注意的是接口不是类,接口是可以多继承的,类只能单继承。接口中的抽象方法都是隐式的,所以声明不需要abstract关键字,接口中的变量只能是 public static final 类型的。当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
接口多态定义的格式:接口 变量名 = new 接口实现类();
2.3抽象类和抽象方法
使用了关键词abstract声明的类叫作"抽象类"。如果一个类里包含了一个或多个抽象方法,类就必须指定成abstract (抽象)。"抽象方法",属于一种不完整的方法,只包含一个方法名,而没有方法体,方法名后面直接跟一个分号,而不是花括号。
抽象类多态定义格式:抽象类 变量名 = new抽象类子类();
3.多态的构成条件
3.1虚函数
虚函数的存在是为了多态。
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。
3.2关键字super
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字super。关键字super代指父类,可以用于调用父类中的普通方法和构造方法。
3.2.1调用父类的构造方法
调用父类构造方法的语法是:super( )或者super(arguments);
语句super( )调用父类的无参构造方法,而语句super(arguments)调用与arguments匹配的父类的构造方法。语句super( )或者super(arguments)必须出现在子类构造方法的第一行,这是显示调用父类构造方法的唯一方式。
3.2.2调用父类的普通方法
调用父类普通方法的语法:super.方法名(参数);
4.多态存在的三个必要条件
4.1继承
继承就是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object。在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。而 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
4.2重写
参考2.1
4.3父类引用指向子类对象
子类是对父类的一个改进和扩充,子类在功能上较父类更强大,属性较父类更独特。该引用只能调用父类中定义的方法和变量;如果子类中重写了父类中的一个方法,在调用此方法时,将会调用子类中动态连接方法;变量不能被覆盖,覆盖的概念只针对方法,如果在子类中重写了父类中的变量,在编译时会报错。
5.动态绑定
将一个方法调用同一个方法主体关联起来称作绑定。如果在程序执行前进行绑定,这种绑定方法称作前期绑定。在面向过程语言中,比如c,这种方法是默认的也是唯一的。如果我们在java中采用前期绑定,很有可能编译器会因为在这庞大的继承实现体系中去绑定哪个方法而感到迷惑。解决的办法就是动态绑定,这种后期绑定的方法,在运行的时候根据对象的类型进行绑定。
在java中,动态绑定是默认的行为。
6.多态的转型和instanceof操作符
如果我们要使用多态,因为父类和子类的类型不一样,子类特有的属性和方法父类的指针是没有用的,所以这时候就需要强制转换,大类型转换成小类型需要强制转换,小类型转换成大类型不需要转换,同理可得,父类向子类转换需要强制转换,子类转换成父类则是自动转换。多态的强制转换可以分为向上强转型和向下转型。
6.1向上转型
子类引用的对象转换为父类对象称为向上转型。通俗地说就是将子类对象转为父类对象,此处父类对象可以是接口。需要注意的是:向上转型时,子类单独定义的方法会丢失;子类引用不能指向父类对象;向上转型可以减少重复代码,使代码变得简洁,也可以提高系统扩展性。
6.2向下转型
一个已经向上转型的子类对象可以使用强制类型转换的格式,把父类对象转为子类对象,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的。需要注意的是:向下转型的前提是父类对象指向的是子类对象(需要先向上转型);向下转型只能转型为本类对象等。
使用格式:子类类型 变量名 = (子类类型) 父类类型的变量;
如:Student stu = (Student) p; //变量p 实际上指向Student对象
6.3instanceof关键字
可以通过instanceof关键字来判断某个对象是否属于某种数据类型。如学生的对象属于学生类,学生的对象也属于人类。