zoukankan      html  css  js  c++  java
  • Java 基础(面向对象特征之三:多态性)

    多态性,是面向对象中最重要的概念,在 JAVA 中的体现:
    对象的多态性: 父类的引用指向子类的对象
    可以直接应用在抽象类和接口上

    Java 引用变量有两个类型:编译时类型 和 运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。
    若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
    多态情况下,"看左边": 看的是父类的引用(父类中不具子类特有的方法)
    "看右边": 看的是子类的对象(实际运行的是子类重写父类的方法)

    理解多态性:可以理解为一个事物的多种形态。

    何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

    多态的使用:虚拟方法调用
    有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
    总结:编译,看左边; 运行,看右边。

    多态性的使用前提:1.类的继承关系,2.方法的重写

    对象的多态性:只话用于方法, 不适用于属性(编译和运行都看左边)

    若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里能同名方法,系统将不可能把父类里的方法转移到子类中。编译看左边,运行看右边。

    对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量。编译运行都看左边。

    举例一

    Person.java

    package com.klvchen.java4;
    
    public class Person {
    	String name;
    	int age;
    
            int id = 1001;
    	
    	public void eat() {
    		System.out.println("人, 吃饭");
    	}
    	
    	public void walk() {
    		System.out.println("人,走路");
    	}
    
    }
    

    Man.java

    package com.klvchen.java4;
    
    public class Man extends Person {
    	
    	boolean isSmoking;
    	
    	public void earnMoney() {
    		System.out.println("男人负责挣钱养家");
    	}
    	
    	public void eat() {
    		System.out.println("男人多吃肉,长肌肉");
    	}
    	
    	public void walk() {
    		System.out.println("男人霸气地走路");
    	}
    }
    

    Woman.java

    package com.klvchen.java4;
    
    public class Woman extends Person {
    	
    	boolean isBeauty;
    	
    	public void goShopping() {
    		System.out.println("女人喜欢购物");
    	}
    
    	public void eat() {
    		System.out.println("女人少吃,为了减肥");
    	}
    	
    	public void walk() {
    		System.out.println("女人窈窕地走路");
    	}
    }
    

    PersonTest.java

    package com.klvchen.java4;
    
    public class PersonTest {
    	public static void main(String[] args) {
    		
    		Person p1 = new Person();
    		
    		p1.eat();
    		
    		Man man = new Man();
    		man.eat();
    		man.age = 25;
    		man.earnMoney();
    		
    		//**************************************
    		System.out.println("***************************************");
    		//对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
    		Person p2 = new Man();
    		//当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 --- 虚拟方法调用
    		p2.eat();
    		p2.walk();
    		
    //		p2.earnMoney();
    
                    System.out.println(p2.id);
    	}
    }
    

    运行结果

    举例二

    AnimalTest.java

    package com.klvchen.java4;
    
    
    public class AnimalTest {
    	
    	public static void main(String[] args) {
    		
    		AnimalTest test = new AnimalTest();
    		test.func(new Dog());
    		
    		System.out.println("*************************************");
    		
    		test.func(new Cat());
    	}
    	
    	public void func(Animal animal) {// Animal animal = new Dog();
    		animal.eat();
    		animal.shout();
    	}
    
    }
    
    
    class Animal{
    	
    	public void eat() {
    		System.out.println("动物, 进食");
    	}
    	
    	public void shout() {
    		System.out.println("动物, 叫");
    	}
    }
    
    
    class Dog extends Animal{
    	public void eat() {
    		System.out.println("狗吃骨头");
    	}
    	
    	public void shout() {
    		System.out.println("汪!汪!汪!");
    	}
    }
    
    class Cat extends Animal{
    	public void eat() {
    		System.out.println("猫吃鱼");
    	}
    	
    	public void shout() {
    		System.out.println("喵!喵!喵!");
    	}
    }
    

    运行结果:

  • 相关阅读:
    JVM 综述
    看 Netty 在 Dubbo 中如何应用
    Netty 心跳服务之 IdleStateHandler 源码分析
    Netty 高性能之道
    Netty 解码器抽象父类 ByteToMessageDecoder 源码解析
    Netty 源码剖析之 unSafe.write 方法
    Netty 出站缓冲区 ChannelOutboundBuffer 源码解析(isWritable 属性的重要性)
    Netty 源码剖析之 unSafe.read 方法
    Netty 内存回收之 noCleaner 策略
    Netty 源码阅读的思考------耗时业务到底该如何处理
  • 原文地址:https://www.cnblogs.com/klvchen/p/14430187.html
Copyright © 2011-2022 走看看