多态
-
Java引用变量有两个类型:
-
编译时类型:由声明该变量时使用的类型决定
-
运行时类型:由实际赋给该变量的对象决定
-
-
如果编译时类型和运行时类型不一致,就可能出现所谓的多态。
-
多态实际上就是,某一个事物,在不同时刻表现出来的不同状态。或者说,同一个变量,调用同一个方法时呈现出的多种不同的行为特征。
例: Cat c=new Cat();
Animal a=new Cat();
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫(); -
多态的前提:
- 有继承关系
- 子类有重写父类的方法(没有也可以,但是多态就会没有意义)
- 父类引用指向子类对象,也就是说编译时类型由父类决定,运行时类型由子类决定。 ji即:父 fname = new 子();
-
多态的优缺点:
- 优点:提高了代码的维护性和延展性。
- 缺点:不能使用子类特有的功能和属性
-
-
多态的使用:
public class MyTest { public static void main(String[] args) { Fu fu = new Zi(); System.out.println(fu.a); //父类引用不能直接访问子类独有的属性 System.out.println(fu.num);//编译出错 fu.show(); //父类引用不能直接访问子类独有的方法 fu.test();//编译出错 //向下转型 Zi zi= (Zi) fu; System.out.println(zi.num); zi.test(); } } class Fu{ int a=10; public void show(){ System.out.println("父类的show方法"); } } class Zi extends Fu{ int num=10; @Override public void show() { System.out.println("重写父类的show方法"); } public void test(){ System.out.println("子类特有的方法"); } } //结果: /* 10 重写父类的show方法 10 子类特有的方法 */
如下为多态的内存图解(网上的)
[外链图片转存失败(img-r44OsLD3-1564286479497)(E:\西部开源\20190413-JavaSE-课件\多态的内存图解.bmp)]
抽象类
-
某些情况下,某个父类只知道它的子类应该包含怎样的方法,但不知道子类如何实现这些方法,我们就可以将该类定义为抽象类,将这些不知如何实现的方法定义为抽象方法。即抽象类中定义的是该继承体系的共性功能。
-
特点:
-
抽象类和抽象方法必须用abstract关键字修饰,且抽象方法不能有方法体:
abstract class name{} public abstract void show();
-
抽象类不能被实例化,抽象类中的构造方法用于子类访问父类数据时的初始化即用于被子类调用。
-
含有抽象方法的类只能被定义为抽象类,也就是说抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
-
抽象类的子类要么重写父类的所有抽象方法,要么也被定义为抽象类。
-
抽象类可以有成员变量,普通方法,构造方法,初始化块,内部类
-
abstract不能喝final,private,static共存
-
-
public class Test { public static void main(String[] args) { Fu p = new Zi(); p.show(); } } abstract class Fu{ int num = 10; public Fu() { } public abstract void show(); public void method(){ System.out.println("抽象类的普通方法"); } } class Zi extends Fu{ int x = 10; public Zi() { } @Override public void show() { System.out.println("重写show()方法"); } }
接口
-
接口是用来定义一些规范(规则)来实现一些扩展功能
-
特点
-
由interface关键字修饰,类实现接口要用implements关键字
-
因为接口中定义的是一种规范,因而接口中没有构造方法
-
接口中的变量默认使用public static final修饰,也就是说接口中只能定义静态常量。
-
接口中的方法必须是抽象方法,类方法(由static修饰的方法)或者默认方法(default修饰的方法),不可以有非抽象方法。
-
类可以实现多个接口:
public class name extends 父类 implements 接口1,接口2... { 类体 }
-
-
public class MyTest { public static void main(String[] args) { A a = new B(); a.show(); //强制向下转型 System.out.println(((B) a).b); } } interface A{ //接口中成员变量前面有默认的修饰符 public static final int num=100; public static final int A=1000; //方法前面存在默认修饰符 public abstract public abstract void show(); } class B implements A{ int b = 0; public B() { } @Override public void show() { System.out.println("重写show方法"); } }