1.多态的概述
1.面向对象有三大特征:封装,继承与多态。
多态是面向对象的三大特征之一,指的是在不同的时刻,所表现出的不同的状态。
举个简单的例子来说,动物中的猫属于猫类型,具体在创建对象时,可以通过Cat cat =new Cat()的代码来进行实现。同时猫也属于动物类型,按照此种逻辑进行推算的话,可以使用父类的引用去接受子类的对象,具体的实现是:Animal an=new Cat(),这种现象就叫做多态。
2.多态的前提
(1)要有继承关系。
(2)要有方法重写。 (其实没有也是可以的,但是如果没有这个就失去了多态的意义。)
(3)要有父类引用指向子类对象。
3.多态访问成员的特点
变量或方法 | 编译和运行 |
成员变量 | 编译看左边,运行看左边。 |
构造方法 | 创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。 |
成员方法 | 编译看左边,运行看右边。 |
静态方法 | 编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问还是左边的) |
这个表是非常重要的。
public class MyTest {
public static void main(String[] args) {
//多态的语法:父类引用指向子类对象
Animal animal = new Cat();
animal.eat();
animal.sleep();
System.out.println("============");
animal = new Dog();
animal.eat();
animal.sleep();
}
}
//父类:将子类中共有的的成员进行抽取
class Animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//子类:猫类
class Cat extends Animal{
public void catchMouse(){
System.out.println("猫抓老鼠");
}
//对父类中的方法进行重写
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫喜欢在太阳下睡觉");
}
}
//子类:狗类
class Dog extends Animal{
public void lookDoor(){
System.out.println("狗看门");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗喜欢在狗窝里睡觉");
}
}
2.多态的好处和弊端
2.1多态的好处
(1)提高了代码的维护性(继承保证)
(2)提高了代码的扩展性(由多态保证)
public class Animal {//父类
public void eat() {
System.out.println("吃饭");
}
}
public class Cat extends Animal {//子类
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal {//子类
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Monkey extends Animal {//子类
@Override
public void eat() {
System.out.println("猴子吃香蕉");
}
}
public final class MyUtils {//一个final修饰的类,方法不可修改,只可继承
private MyUtils() { }
public static void testEat(Animal an) {//静态方法,用类名调用
an.eat();
}
}
public class MyTest {
public static void main(String[] args) {
Cat cat = new Cat();
MyUtils.testEat(cat);
Dog dog = new Dog();
Dog dog1 = new Dog();
MyUtils.testEat(dog);
MyUtils.testEat(dog1);
Monkey monkey = new Monkey();
MyUtils.testEat(monkey);
}
}
2.2多态的弊端
多态最大的一个弊端就是不能使用子类中特有的功能。这是需要用到向下转型才能使用子类的特有功能。
解决方法:把父类的引用强制转换为子类的引用。
class Animal {
int num = 20;
public void eat() {
System.out.println("吃饭");
}
}
class Cat extends Animal {
int num = 500;
int age = 2;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal {
int num = 900;
int age = 800;
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void lookDoor() {
System.out.println("狗看门");
}
}
public class MyTest {
public static void main(String[] args) {
/* Animal an = new Cat(); //多态就是向上转型。
an.eat();
System.out.println(an.num);//
//多态的形式,不能直接调用子类特有的功能
//an.catchMouse();
//如果你要调用子类特有的方法,你可以向下转型,你可以把父类引用,转换成子类对象
Cat cat = (Cat) an; //向下转型。
System.out.println(cat.num);
cat.catchMouse();
*/
Animal an = new Cat();
an.eat();
//向下转型
Cat cat = (Cat) an;
cat.catchMouse();
an = new Dog();
Dog dog = (Dog) an;
dog.lookDoor();
}
}
3.代码分析题
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show();
B b = new C();
b.show();
}
}