Java多态

Java多态

  • 多态:(多种形态)是同一个行为具有多个不同表示形式或形态的能力,多态就是同一个接口,使用不同的实例而执行不同的操作.
优点
  • 1.消除类型之间的耦合关系.
  • 2.可替换性
  • 3.可扩充性
  • 4.接口性
  • 5.灵活性
  • 6.简化性
必要条件
  • 1.继承
  • 2.重写
  • 3.父类引用变量指向子类对象
	父类类型  变量名 = new 子类类型();
	变量名.方法名();
  • 普通类多态定义的格式
public class Zi extends Fu{}
public class Fu {}

Fu f = new Zi();

注意:当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,如果有,再去调用子类的同名方法.使用多态的好处是:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理.

案例

/**
 * 多态
 */
public class HelloPolymorphic {
    public static void main(String[] args) {
        // 以 Cat 对象调用 show 方法
        show(new Cat());
        // 以 Dog 对象调用 show 方法
        show(new Dog());

        // 向上转型:通过子类对象 (小范围) 实例化父类对象 (大范围),这种属于自动转换
        Animal a = new Cat();
        // 调用的是 Cat 的 eat
        a.eat();
        // 向下转型:父类强制转换为子类,从而调用子类独有的方法
        Cat c = (Cat) a;
        // 调用的是 Cat 的 work
        c.work();
    }

    public static void show(Animal a) {
        a.eat();
        // 类型判断 比较运算符:instanceof 返回值的类型是boolean
        if (a instanceof Cat) {
            // 猫做的事情
            Cat c = (Cat) a;
            c.work();
        }
        // 狗做的事情
        else if (a instanceof Dog) {
            Dog c = (Dog) a;
            c.work();
        }
    }
}

abstract class Animal {
    abstract void eat();
}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }

    public void work() {
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("吃骨头");
    }

    public void work() {
        System.out.println("看家");
    }
}
  • 输出的顺序
	吃鱼
	抓老鼠
	吃骨头
	看家
	吃鱼
	抓老鼠

实现方式

  • 1.重写
  • 2.接口
  • 3.抽象类和抽象方法

多态- 成员的特点

  • 前面学习继承时,我们知道子父类之间成员变量有了自己的特定变化,那么当多态出现后,会导致子父类中的成员变量有微弱的变化
public class Fu {
	int num = 4;
	public void show() {
		System.out.println("Fu");
	}
}

public class Zi extends Fu {
	int num = 5;
	public void show() {
		System.out.println("Zi");
	}
}

public class Demo {
    public static void main(String[] args) 	{
        Fu f = new Zi();
        System.out.println(f.num); // 4
        f.show(); // Zi
    }
}
  • 调用方法看等号右边,调用属性看等号左边
附:扩展阅读
向上转型与向下转型
概述:

父子对象0之间的转换分为了向上转型和向下转型,它们的区别如下:

  • 向上转型:通过子类对象(小范围)实例化父类对象(大范围),这种属于自动转换;
  • 向下转型:通过父类对象(大范围)实例化子类对象(小范围),这种属于强制转换.
public class HelloUp{
	public static void main(String[] args){
		//通过子类去实例化父类
		Fu f = new Zi(); 
		a.print();//结果是:Zi:print
	}
}
class Fu{
	public void print(){
		System.out.println("Fu:print")
	}
}
class Zi extends Fu{
	@Oerride
	public void print(){
		System.out.println("Zi:print")
	}
}
  • 可以看到打印的是 class Zi 的print,这是因为我们通过子类Zi去实例化的,所以父类 Fu 的print方法已经被子类Zi的print方法覆盖了,从而打印class Zi 的print.
**注意**:其意义在于但我们需要多个同父的对象调用某个方法时,通过向上转换后,通过向上转换后,则可以确定参数的统一。方便程序设计

向下转型(instanceof)

Java中,向下转型则是为了通过父类强制转换为子类,从而调用子类特有的方法,为了保证向下转型的顺利完成,在Java中提供一个关键字instanceof通过 instanceof 可以判断某对象是否是某类的实例,如果是则返回 true, 否则为 false.

	// 向上转型 (B 是 A 的子类)
	A a = new B();
	
	// 返回 true
	a instanceof A;
	// 返回 true
	a instanceof B;
	// 返回 false
	a instanceof C;
package com.funtl.oop.demo5;

/**
 * 向下转型
 */
public class HelloDown {
    public static void func(A a) {
        a.print();
        if (a instanceof B) {
            // 向下转型,通过父类实例化子类
            B b = (B) a;
            // 调用 B 类独有的方法
            b.funcB();
        } else if (a instanceof C) {
            // 向下转型,通过父类实例化子类
            C c = (C) a;
            // 调用 C 类独有的方法
            c.funcC();
        }
    }

    public static void main(String args[]) {
        func(new A());
        func(new B());
        func(new C());
    }
}

class A {
    public void print() {
        System.out.println("A:print");
    }
}

class B extends A {
    @Override
    public void print() {
        System.out.println("B:print");
    }

    public void funcB() {
        System.out.println("funcB");
    }
}

class C extends A {
    @Override
    public void print() {
        System.out.println("C:print");
    }

    public void funcC() {
        System.out.println("funcC");
    }
}
  • 输出顺序如下
A:print
B:print
funcB
C:print
funcC

通过输出结果我们可以看到成功通过向下转型来调用 B 类和 C 类独有的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值