Java 多态基础及应用

前言

面向对象程序设计的三大支柱是封装、继承和多态。继承关系使一个子类能继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例是其父类的实例,但是反过来不成立、因此、总可以将子类的实例传给需要父类型的参数。多态就意味着父类型的变量可以引用子类型的参数。

向上转型和向下转型

在我们学习程序设计语言的过程中,我们似乎总能用到强制类型转换,比如将一个String类型转换为int类型。而像这样的转型是有前提的,那就是:这两个类型是否存在着某种关联关系。

由此我们就可以联想到类:类与类之间是否可以相互转换呢?这里我们就要说到向上转型了。

向上转型(upcasting):

public class Human {
	public void sleep() {
	    System.out.println("Human sleep..");
	}
	
    public static void main(String[] args) {
    	Male m = new Male();
	    m.sleep();
	    
	    Human h = new Male();// (1) 向上转型
	    h.sleep();   //(2)动态绑定
	    //h.speak();  //(3)此方法不能编译,报错说Human类没有此方法
    }
}
	    
	
	class Male extends Human {
		@Override
		public void sleep() {
			System.out.println("Male sleep.");
		}
		public void speak () {
			System.out.println("I am Male");
	}
}
	
	class Female extends Human {
		
	@Override
	public void sleep() {
		System.out.println("Female sleep.");
	}
	public void speak() {
		System.out.println("I am Female");
	}

}

运行结果为:Male sleep.

                      Male sleep.

仔细研究上方代码,我们可以发现,Human类是Male类和Female类的父类。在主方法中,我们可以看到声明了一个Male对象m,再调用了m的sleep方法,很显然这句话会输出Male sleep. 

但是当声明h对象时,却出现了两个类,其中h的声明类型是Human类(父类),实际类型则是Male类,调用h.sleep()方法,会输出 Male sleep. 调用h.speak()方法则会出错。

由此我们可以知道向上转型:1、向上转型不要强制转型。2、父类引用指向的或者调用的方法是子类的方法,这个叫动态绑定 。3、向上转型后,父类应用不能调用子类自己的办法。

向下转型(downcasting):

//接上段

//向下转型:成功
Male m2 = new Male();
Human h2 = m2;       //向上转型
m2 = (Male)h2;       //向下转型
m2.speak();

//向下转型:失败
Human h3 = new Human();
Male m3 = (Male)h3;
m3.speak();         //运行时会出现错误,可以用instanceof诊断

//向下转型:类型防护
Human h4 = new Human();
if (h4 instanceof Male){  //因为h4不是Male的实例,所以不执行if内部代码
    Male m4 = (Male)h4;
    m4.speak;
}

向下转型一般用的比较少。

instanceof关键字:

作用:用来判断某个对象是否属于某种数据类型。

注意:返回类型为布尔类型

其实多态的核心就是向上转型。

所以说,多态的定义与使用格式就是: 定义格式:父类类型 变量名=new 子类类型();

多态的应用

多态:父类型对象访问子类型重写的方法。

使用场景:1、循环调用父类对象,访问不同派生类方法。

                  2、实参是子类,形参是父类。

场景一应用:

//Person类
public class Person {
	private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say() { // 返回名字和年龄
        return name + "\t" + age;
    }
}
//Student类
public class Student extends Person {
	private double score;

    public Student() {
    }

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public Student(String name, int age) {
        super(name, age);
    }

    public Student(double score) {
        this.score = score;
    }

    //重写父类say方法
    @Override
    public String say() {
        return super.say() + " score=" + score;
    }

    //学生特有的方法
    public void study() {
        System.out.println("学生 " + getName() + "正在学java");
    }

}
//Teacher类
public class Teacher extends Person {
	 public double salary;

	    public Teacher(String name, int age, double salary) {
	        super(name, age);
	        this.salary = salary;
	    }

	    public double getSalary() {
	        return salary;
	    }

	    public void setSalary(double salary) {
	        this.salary = salary;
	    }

	    @Override
	    public String say() {
	        return super.say() + " salary=" + salary;
	    }

	    //特有的方法
	    public void teach() {
	        System.out.println("老师" + getName() + "正在讲java课程");
	    }
}
public class PloyArray {

	public static void main(String[] args) {
		Person[] persons = new Person[5];
        persons[0] = new Person("jack", 20);
        persons[1] = new Student("jack", 18, 100);
        persons[2] = new Student("smith", 19, 30.1);
        persons[3] = new Teacher("scott", 30, 20000);
        persons[4] = new Teacher("king", 50, 25000);

        for (int i = 0; i < persons.length; i++) {
              System.out.println(persons[i].say());
//            System.out.println(persons[i] instanceof Person);
//            if (persons[i] instanceof Student) {
//                ((Student)persons[i]).study();
//            } else if (persons[i] instanceof Teacher) {
//                ((Teacher)persons[i]).teach();
//            }
        }

	}

}

 

场景二应用:

package Sample;

public class DynamicBindingDemo {

	public static void main(String[] args) {
		m(new GraduateStudent());
		m(new Student());
		m(new Person());
		m(new Object());
	}
	public static void m(Object x) {
		System.out.println(x.toString());
	}
}
class GraduateStudent extends Student {
}

class Student extends Person {
	@Override
	public String toString() {
		return "Student";
	}
}
class Person extends Object {
	@Override 
	public String toString() {
		return "Person";
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值