zoukankan      html  css  js  c++  java
  • Java基础教程——多态

    直观地说,多态就是“一个对象,多种形态 ”。比如观世音菩萨就有多种形态——

    每个人都有多种形态——


    具体地讲,多态是指“同一个对象、同一个方法(函数),表现出不同的行为”。
    在代码层面表现为:父类对象指向子类实例;父类对象 调用(多种)子类方法。比如:

    List lst; // lst以List的形式定义
    lst = new ArrayList();// 实例化的时候却是子类对象
    lst = new LinkedList(); // 可以是不同的子类对象
    

    底层技术:后期绑定(动态绑定/运行时绑定),根据运行时期对象实例来动态判断要调用的方法。


    示例:开车

    一般考驾照是C1驾照,可以开多种小型汽车:
    在这里插入图片描述
    现定义一个汽车类,两个子类分别是“小货车”、“三蹦子”。
    主类“驾照”类中编写main方法,可以分别创建两种子类的车对象,并分别调用其"驾驶()"方法。代码如下——

    public class 驾照 {
    	public static void main(String[] args) {
    		小货车 b = new 小货车();
    		b.行驶();
    		三蹦子 c = new 三蹦子();
    		c.行驶();
    	}
    }
    class 汽车 {
    	public void 行驶() {
    		System.out.println("启动理论");
    	}
    }
    class 小货车 extends 汽车 {
    	public void 行驶() {
    		System.out.println("小货车");
    	}
    }
    class 三蹦子 extends 汽车 {
    	public void 行驶() {
    		System.out.println("三蹦子");
    	}
    }
    

    上例中定义了两个对象,分别是b和c,可以理解为开小货车需要先了解小货车,开三蹦子需要先了解三蹦子,有点麻烦。
    能不能一照到手,随便开车?

    	public static void main(String[] args) {
    		// 小货车 b = new 小货车();
    		// b.行驶();
    		// 三蹦子 c = new 三蹦子();
    		// c.行驶();
    		汽车 c;
    		c = new 小货车();
    		c.行驶();
    		c = new 三蹦子();
    		c.行驶();
    	}
    

    修改后的代码只声明了一个对象c,属于父类的实例对象,可以分别实例化为子类,虽然方法调用都是“c.行驶()”,但输出的结果是不同的。这就是多态。

    向上转型,向下转型

    以父类的名义实例化一个子类对象,属于向上转型。
    向上转型,是自动提升的。因为上层更抽象,范围更大,没什么问题;

    小货车也是车,用更抽象的上层代表下层没有问题。
    但是如果说车是小货车,就不一定对了,这个属于向下转型。

    向下转型,需要强制转换。因为下层更具体,可能有父类未定义的方法,转型不一定安全。

    下面的代码演示了使用括号进行强制的向下转型——

    public class 多态转型 {
    	public static void main(String[] args) {
    		Animal _animal = null;
    		Cat _cat = new Cat();
    		_animal = _cat;// 向上转型(自动提升):猫是动物,没问题
    		_cat = (Cat) _animal;// 向下转型(强制转换):动物未必都是猫
    		// ↑↑↑之所以向下转型成功,是因为_animal本就是Cat,属于还原;
    		// -----------
    		// 动物有可能不是猫,转型可能出错
    		_animal = new Dog();
    		_cat = (Cat) _animal;// ClassCastException
    		// 即使是单纯的父类实例对象,向下转型也会失败
    		_animal = new Animal();
    		_cat = (Cat) _animal;// ClassCastException
    	}
    }
    class Animal {
    }
    class Cat extends Animal {
    }
    class Dog extends Animal {
    }
    

    另一个示例:String类是Object的子类

    		String s ="太上老君";
    		Object o = s;// 向上转型(自动提升)
    		s = (String)o;// 向下转型(强制转换)
    

    instanceof运算符

    用于判断左边的对象是否属于右边的类型(实例、子类实例)。
    如果左边对象和右边类没有继承关系,编译会出错。

    public class 多态转型 {
    	public static void main(String[] args) {
    		Animal _animal = new Cat();
    		System.out.println(_animal instanceof Cat);
    		System.out.println(_animal instanceof Animal);
    		System.out.println(_animal instanceof Dog);
    		System.out.println(_animal instanceof Object);
    		// 和String类没有继承关系,编译无法通过
    		// System.out.println(_animal instanceof String);
    		// ----------------------
    		// 先判断,再转换
    		if (_animal instanceof Cat) {
    			Cat _cat = (Cat) _animal;
    			System.out.println(_cat.getClass());
    		}
    	}
    }
    class Animal {
    }
    class Cat extends Animal {
    }
    class Dog extends Animal {
    }
    

    结果:

    true
    true
    false
    true
    class Cat
    
  • 相关阅读:
    Apache的443端口被占用解决方法
    关于变量初始化问题
    浏览无法加载控件
    关于网络数据传输
    java 对象是在什么时候创建的?
    HTML HTTP
    2020 年计划
    Docker 学习
    [腾讯 TMQ] 接口测试用例设计
    pytest + request
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11179160.html
Copyright © 2011-2022 走看看