面向对象_多态、抽象
A.多态
1)概念
指的是一个事物,在不同时刻状态的一个提现
Dog d = new Dog(); //创建了一个狗类的对象
Animal a = new Dog(); //狗是一个动物
2)多态的前提条件
1.必须有继承关系
2.继承一个类的同时,子类中必须有方法重写(使用子类中的方法去覆盖父类中的方法)
动物类:吃和睡的功能,子类重写父类方法的的原因:使用子类中有具体的功能...
3.父类的引用指向子类对象
继承的时候:使用子类的:Zi z = new Zi();
Fu f = new Zi(); //将代表的父类引用指向对内存的子类的对象
向上转型!
3)多态中的成员访问特点
成员变量:编译看左,运行看左
非静态成员方法:编译看左,运行看右
静态成员方法:编译看左,运行看左
构造方法:始终是给对象进行初始化的!
class Fu { public int num = 20; public Fu() { } public void show() { System.out.println("show Fu..."); } public static void method() { System.out.println("method FU..."); } } class Zi extends Fu { int num = 30; public Zi() { } public void show() { System.out.println("show Zi..."); } public static void method() { System.out.println("method Zi..."); } } public class Demo03 { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num); // 编译看左, f.show(); // 编译看左,运行看右 f.method(); // 编译看左,运行看左 } }
4)多态的好处
提高了代码的维护性(由继承保证)
提高了代码的扩展性(由多态保证)
5)多态的弊端
父类不能访问子类特有的功能
解决方案:
a.创建子类对象,调用本类自己的方法(这种方式不好,从内存角度考虑,耗内存)
b.不创建子类对象,可不可以使用子类对象呢?
可以,父类的引用指向子类对象,把父类的引用强制转换为子类对象
向下转型
Fu f = new Zi(); //向上转型
Zi z = (Zi)(f); // 向下转型
6)向下转型容易出现的异常
类转换异常:ClassCastException:
7)多态的成员访问特点以及理解(孔子装爹案例)
class 孔子爹 { public int age = 40; public void teach() { System.out.println("将JavaEE..."); } } class 孔子 extends 孔子爹 { public int age = 20; public void teach() { System.out.println("讲论语..."); } public void playGame() { System.out.println("玩lol..."); } } public class Demo03 { public static void main(String[] args) { /* * 孔子爹由于请他讲课的人非常多,孔子也想去别人家讲课 戴上一副眼睛,粘上胡子,然后开始装爹 */ // 向上转型 孔子爹 kd = new 孔子(); System.out.println(kd.age); // 40:编译看左,运行看左 kd.teach(); // 将论语 露馅 编译看左,运行看右 // 孔子讲课回来,脱下爹的装备 // 向下转型 孔子 k = (孔子) kd; System.out.println(k.age); // 20 k.teach(); // 将论语 k.playGame();// 玩游戏 } }
B.抽象
1)概述
将功能定义抽象,那么该类就是抽象类
动物有很多,应该将动物类定义为一个抽下类,动物本身不是一个具体动物
猫和狗具体的事物,吃的方法不一样,在动物类中,把吃定义为抽象方法
java针对一个类定义为抽象-----abstract:抽象的意思
2)抽象类的特点
一个类中可以有抽象方法,也可以由非抽象方法
抽象方法的格式:public abstract void method();
3)抽象子类的特点
子类可以是抽象类,没有任何意义!抽象类不能直接实例化,就不能调用方法!
子类是非抽象类,必须要重写父类中的抽象方法,然后去使用子类的自己的功能
父类是一个抽象类,如果要创建对象,就必须通过子类进行实现
父类进行实例化只能间接通过子类进行实例化
abstract class Animal { // 非抽象方法 public void show() { } // 抽象方法 public abstract void eat(); // 空语句体 public abstract void sleep(); } class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼..."); } @Override public void sleep() { System.out.println("猫趴着睡..."); } } class Dog extends Animal { @Override public void eat() { System.out.println("狗啃骨头..."); } @Override public void sleep() { System.out.println("狗卧着睡..."); } } public class Demo03 { public static void main(String[] args) { // 创建动物类对象 // Animal a = new Animal();//抽象类不能直接实例化 // 使用子类具体功能,就需要创建子类对象 // Cat c = new Cat(); Animal a = new Cat();// 属于多态的第三个条件 a.eat(); a.sleep(); } }
4)抽象类中成员的特点
成员变量:可以是变量,也可以是常量
成员方法:可以是抽象方法,也可以是非抽象方法
构造方法:一个抽象类中是可以有构造方法的
抽象类这个抽象方法是强制要求子类必须实现的方法
abstract class Fu { // 定义变量 public int num = 10; // 定义一个常量 final public int num2 = 20; public Fu() { } // 非抽象方法 public void show() { System.out.println("show Fu"); } // 抽象方法 public abstract void method(); } class Zi extends Fu { @Override public void method() { System.out.println("method Zi"); } } public class Demo03 { public static void main(String[] args) { // 创建对象 Fu f = new Zi(); System.out.println(f.num); System.out.println(f.num2); f.show(); f.method(); } }
5)abstract不能和以下的关键字共用
关键字:private,final,static
private:冲突(要么public/protected)
final:冲突
static:无意义
抽象的成员方法修饰:public(使用的比较多)