Java多态

1.关于Java的多态

1.1什么是Java多态的概念

        面向对象程序设计的三大支柱是封装、继承和多态。

继承关系使一个子类能继承父类的特征,并且附加一些新特性。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来不成立。因此总可以将子类的实例传递给需要父类型的参数。使用父类对象的地方都可以使用子类的对象,这就是通常所说的多态(polymorphism)。简单来说,多态意味着父类型的变量可以引用子类型的对象。

1.2Java多态的实例

实例:

1.	public class PolymorphismDemo {  
2.	    /** Main method */  
3.	    public static void main(String[] args) {  
4.	        displayObject(new Circle(1, "red", false));  
5.	        displayObject(new Rectangle(1, 1, "black", true));  
6.	          
7.	    }  
8.	      
9.	    /** Display geometric object properties */  
10.	    public static void displayObject(GeometricObject object) {  
11.	        System.out.println("Created on " + object.getDateCreated() +   
12.	                ". Color is " + object.getColor());  
13.	    }  
14.	}  

输出:

1.	Created on Thu Apr 21 10:46:30 CST 2022. Color is red  
2.	Created on Thu Apr 21 10:46:30 CST 2022. Color is black 

        Circle和Rectangle都是GeometricObject的子类,方法displayObject(第10行)具有GeometricObject类型的参数。可以传递任何一个GeometricObject的实例来调用,Circle和Rectangle的实例都是GeometricObject的实例,所以第4行和第5行对displayObject的调用是正确的。

2.动态绑定

2.1动态绑定与多态

      多态是动态绑定的的使用,动态绑定是多态的实现原理。

2.2什么是动态绑定

示例代码:

1.	Object o = new GeometricObject();  
2.	System.out.println(o.toString()); 

一个变量必须被声明为某种类型,变量的这个类型称为它的声明类型(declared type)。例如这里o的声明类型就是Object。

一个引用类型变量可以是一个null值或者是对一个声明类型实例的引用。实例可以是使用声明类型或它的子类型的构造方法创建。变量的实际类型(actual type)是被引用的对象的实际类。例如这里,o的实际类型是GeometricObject,因为o引用使用new GeometricObject()创建的对象。o调用哪个toString()由o的实际类型决定,这就称为动态绑定(dynamic bingding)

2.3类型转换

      1.向上转型不要强制转换

2.父类引用指向的或者调用的方法是子类的方法,这个叫动态绑定

3.向上转型后父类引用不能调用子类自己的方法

例子:

1.	public class Human {  
2.	    public void sleep() {  
3.	        System.out.println("Human sleep..");  
4.	    }  
5.	    public static void main(String[] args) {  
6.	    // (1)向上转型  
7.	        Male m1 = new Male();  
8.	        Human h1 = m1;        
9.	        h1.sleep();  
10.	        //h1.speak();  // 此时需要向下转型,否则不能调用speak方法。  
11.	          
12.	//        // (2)向下转型  
13.	//        Male m2 = new Male();  
14.	//        Human h2 = m2;    
15.	//        m2 = (Male) h2;           
16.	//        m2.speak();   
17.	          
18.	//        // (3)向下转型:失败  
19.	//        Human h3 = new Human();  
20.	//        Male m3 = (Male)h3;  
21.	//        m3.speak();               //此时会出现运行时错误,所以可以用instanceOF判断   
22.	//          
23.	//        // (4)向下转型:类型防护  
24.	//        Human h4 = new Human();  
25.	//        if (h4 instanceof Male){  // 因为h4不是Male的实例,所以不执行if内部代码  
26.	//             Male m4 = (Male)h4;  
27.	//             m4.speak();  
28.	//        }  
29.	    }  
30.	}  
31.	class Male extends Human {  
32.	    @Override  
33.	    public void sleep() {  
34.	        System.out.println("Male sleep..");  
35.	    }  
36.	
  
37.	    public void speak() {  
38.	        System.out.println("I am Male");  
39.	    }  
40.	} 

2.4动态绑定的工作机制

      假设对象o是类C1, C2, …, Cn-1, Cn的实例,其中C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类。即Cn是最通用的类,C1是最特殊的类。如果对象o调用一个方法p,那么JVM会依次在类C1, C2, …, Cn-1, Cn中查找方法p的实现,直到找到为止。

例子:

1.	public class DynamicBindingDemo {  
2.	    public static void main(String[] args) {  
3.	        m(new GraduateStudent());  
4.	        m(new Student());  
5.	        m(new Person());  
6.	        m(new Object());  
7.	    }  
8.	      
9.	    public static void m(Object x) {  
10.	        System.out.println(x.toString());  
11.	    }  
12.	  
13.	}  
14.	  
15.	class GraduateStudent extends Student {  
16.	}  
17.	  
18.	class Student extends Person {  
19.	    @Override  
20.	    public String toString() {  
21.	        return "Stuendt";  
22.	    }  
23.	}  
24.	  
25.	class Person extends Object {  
26.	    @Override  
27.	    public String toString() {  
28.	        return "Person";  
29.	    }  
30.	}  

输出:

1.	Student  
2.	Student  
3.	Person  
4.	java.long.Object@130c19b

3.多态应用

为了进行通用程序设计,好的做法是把变量定义为父类型,这样,它可以接受任何子类型

例子:

1.	public class CastingDemo {  
2.	    /** Main method */  
3.	    public static void main(String[] args) {  
4.	        // Create and initialize two objects  
5.	        Object object1 = new Circle(1);  
6.	        Object object2 = new Rectangle(1, 1);  
7.	          
8.	        // Display circle and rectangle  
9.	        displayObject(object1);  
10.	        displayObject(object2);  
11.	    }  
12.	      
13.	    /** A method for dispalying an object */  
14.	    public static void displayObject(Object object) {  
15.	        if (object instanceof Circle) {  
16.	            System.out.println("The cielce area is " +  
17.	                ((Circle)object).getArea());  
18.	            System.out.println("The circle diameter is " +   
19.	                ((Circle)object).getDiameter());  
20.	        }  
21.	        else if (object instanceof Rectangle) {  
22.	            System.out.println("The rectangle area is " +   
23.	                 ((Rectangle)object).getArea());  
24.	        }  
25.	    }  
26.	  
27.	}  

输出:

1.	The cielce area is 3.141592653589793  
2.	The circle diameter is 2.0  
3.	The rectangle area is 1.0 

4.抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。在Java语言中使用 abstract 来定义抽象类和抽象方法。

抽象方法是出现在基类中的一种方法,但要求在派生类中被重写。一个抽象方法只有方法头,没有方法主体。例如:

  1. public abstract void getArea();  

若类含有抽象方法,则类必须以abstract关键字声明为抽象类。

  1. public abstract class 类名  

注意:

  1. 抽象类可以含零至多个普通方法,也可以含零至多个抽象方法。
  2. 不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。
  3. 不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。

例子:

1.	public abstract class Employee  
2.	{  
3.	   private String name;  
4.	   private String address;  
5.	   private int number;  
6.	     
7.	   public abstract double computePay();  
8.	     
9.	   //其余代码  
10.	} 
1.	/* 文件名 : Salary.java */  
2.	public class Salary extends Employee  
3.	{  
4.	   private double salary; // Annual salary  
5.	    
6.	   public double computePay()  
7.	   {  
8.	      System.out.println("Computing salary pay for " + getName());  
9.	      return salary/52;  
10.	   }  
11.	   
12.	   //其余代码  
13.	}  

        Employee类是抽象类含有抽象方法computePay不允许实例化。Salary类是Employee类的子类并且重写了computePay方法,Salary类不是抽象类,可以实例化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值