• Java多态学习笔记


              面向对象三大特性:封装,继承和多态。其中,封装,继承都比较通俗易懂,唯有多态令我甚是头疼。经过仔细研究之后,终于搞懂了一点,特来做一个分享。独乐乐不如众乐乐。


             何为多态?多态的本质是:一个程序中同名的不同方法。在面向对象的程序设计中,多态主要有以下三种方式来实现。


    (1)、通过子类对父类方法的覆盖来实现多态。

    (2)、通过一个类中方法的重载来实现多态。

    (3)、通过将子类的对象作为父类的对象实现多态。


    其中,前俩中方法比较容易理解,我们重点阐述第三种实现方法。


            把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。(这句话是我理解第三种方法的关键,请仔细阅读理解)

            对象的引用型变量是具有多态性的,因为一个引用型变量可以指向不同形式的对象,即:子类对象作为父类对象来使用。

    举一个例子,在一个单位中,有职工employee,职工中又有少数是管理者manager,管理者中又有一部分是领导。若小明是管理者manager类的对象,他也可以被看做是employee的对象,即他也可以被看做是一个职工,他同时具备着职工的所有属性。


    代码如下:

    public class testDuoTai {
    
    	public static void main(String[] args) {
    		Employee emp1=new Employee("小明",23, 1000);   //emp1是Employee的对象
            System.out.println(emp1.getInfo());
            
            Employee emp2=new Manager("小明",23, 1000,5000); //注意此处emp2是Manager类的对象
            System.out.println(emp2.getInfo());
    	}
    
    }
    //定义一个父类
    class Employee
    {
    	String name;
    	int age;
    	float salary;
    	
    	Employee(){};
    	
    	Employee(String name,int age,float sal)
    	{
    		this.name=name;
    		this.age=age;
    		this.salary=sal;				
    	}
    	String getInfo()
    	{
    		return "职工姓名:"+name+"年龄:"+age+"工资:"+salary;
    	}
    }
    //定义一个子类
    class Manager extends Employee
    {
    	float allowance;
    	Manager(String name,int age,float sal,float aa)
    	{
    		this.name=name;
    		this.age=age;
    		this.salary=sal;
    		allowance=aa;
    	}
    }
    
    

    输出结果如下:
    职工姓名:小明年龄:23工资:1000.0
    职工姓名:小明年龄:23工资:1000.0

    此案例中,充分体现了多态性。即子类的对象可以作为父类的对象来使用。

    再来看一道牛客网专项练习题:

     

    下面代码的输出是什么?

    public class Base
    {
        private String baseName = "base";
        public Base()
        {
            callName();
        }
     
        public void callName()
        {
            System. out. println(baseName);
        }
     
        static class Sub extends Base
        {
            private String baseName = "sub";
            public void callName()
            {
                System. out. println (baseName) ;
            }
        }
        public static void main(String[] args)
        {
            Base b = new Sub();
        }
    }

    A null                  B  sub              C  base

    正确答案:A


    解析:本题与内部类无关系,去掉内部类后代码如下:

    public class Base {
        private String baseName = "base";
        public Base() {
            callName();
        }
        public void callName() {
            System.out.println(baseName);
        }
        public static void main(String[] args) {
            Base b = new Sub();
        }
    }
    class Sub extends Base {
        private String baseName = "sub";
        public void callName() {
            System.out.println(baseName);
        }
    }

            执行 Base b = new Sub();时由于多态 b编译时表现为Base类特性,运行时表现为Sub类特性,Base b = new Sub();不管是哪

    种状态都会调用Base构造器执行 callName()方法;执行方法时,由于多台表现为子类特性,所以会先在子类是否有 callName();

    此时子类尚未初始化(执行完父类构造器后才会开始执行子类),如果有就执行,没有再去父类寻找。



  • 相关阅读:
    分西瓜(dfs)
    括号配对(栈)
    gcd表(欧几里得定理)
    整数性质(拓展欧几里得算法)
    欧几里得算法(求最大公约数)拓展欧几里得算法
    删除元素(二分查找)
    括号配对问题
    公司组织看电影(综合)
    取余数(%)
    幼儿园分苹果(/)
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467339.html
Copyright © 2020-2023  润新知