多态概述:指某一个事物在不同时刻表现出的不同状态。
多态前提:1.要有继承关系
2.要有方法的重写
3.有父类的引用指向子类
多态访问成员的特点:
1、成员变量:编译看左,运行看左
2、成员方法:编译看左,运行看右
3、静态成员方法:编译看左,运行看左
4、构造方法:创建子类对象的时候,先访问父类中的构造方法,对父类的数据进行初始化
class Fu1{
int num=10;
public void show(){
System.out.println("这是父类中的show方法");
}
public static void fun(){
System.out.println("这是父类中的静态fun方法");
}
}
class Zi1 extends Fu1{
int num =20;
@Override //方法重写
public void show() {
System.out.println("这是子类中的show方法");
}
public void show1(){
System.out.println("这是子类中的特有show1方法");
}
public static void fun(){
System.out.println("这是子类中的静态的fun方法");
}
}
public class DuoTai {
public static void main(String[] args) {
//多态创建了一个对象
Fu1 f=new Zi1();
System.out.println(f.num); //编译看左,运行看左 10
f.show(); //编译看左,运行看右。 这是子类中的show方法
f.fun(); //编译看左,运行也看左。 这是父类中的静态fun方法
}
}
运行结果:
多态的好处:
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
多态的弊端:
不能访问子类特有功能
多态的转型:向上转型 从子到父 父类引用指向子类对象
向下转型 从父到子 父类引用转为子类对象
1、向上转型: Fu f = new Son(); 2、向下转型 Son s = (Son)f;
将父类的引用强制转换成子类的引用
子类类名 变量名 = (子类类名)父类的引用;
class Fu2 {
public void show() {
System.out.println("这是父类中的show方法");
}
}
class Son2 extends Fu2 {
@Override
public void show() {
System.out.println("这是子类中的show方法");
}
public void show2() {
System.out.println("这是子类中特有的方法");
}
}
public class TextDemo {
public static void main(String[] args) {
Fu2 f = new Son2();
// 将父类的引用进行向下转型
// 子类类名 变量名 = (子类类名)父类的引用;
Son2 s = (Son2) f;
s.show2();
}
}
抽象的概述:我们把不具体的功能叫做抽象方法,如果一个类中有抽象方法,我们就把这个类称为抽象类。
特点:
1、抽象类和抽象方法都有一个关键字修饰:abstract
修饰一个类 放在class前面
abstra class animal{}
修饰一个方法 一般是放在权限修饰符后面
定义一个抽象的show方法
public abstract void show();
2、抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
3、抽象类不能实例化
那么,抽象类如何实例化呢? 按照多态的方式,由具体的子类实例化。其实这也是多的一种,抽象类多态。
4、如果继承抽象类的是一个具体的子类,需要重写该抽象类中所有的抽象方法 如果继承抽象的也是一个抽象类,可以不去重写父类中的抽象方法,也可以选择性的去重写。
//定义了一个抽象类,叫Animal
abstract class Animal{
//注意:
//抽象方法没有方法体{},连大括号都没有,直接以分号结尾
//java: 抽象方法不能有主体
public abstract void eat();
public abstract void drink();
}
class Dog extends Animal{
@Override //如果继承抽象类的是一个具体的子类,需要重写该抽象类中所有的抽象方法
public void eat() {
System.out.println("狗吃肉");
}
@Override
public void drink() {
System.out.println("狗喝水");
}
}
abstract class Demo{
public abstract void fun();
public abstract void fun2();
}
abstract class Demo2 extends Demo{
@Override //如果继承抽象的也是一个抽象类,可以不去重写父类中的抽象方法,也可以选择性的去重写。
public void fun() {
System.out.println("抽象类Dem2中重写了fun方法");
}
}
public class AbstractDemo {
public static void main(String[] args) {
Animal a=new Dog();
a.eat();
a.drink();
}
}
运行结果: