Java学习笔记(33)-- Java 多态的详解

来源:互联网 发布:制作livephoto的软件 编辑:程序博客网 时间:2024/06/07 23:35

1.什么是多态?

一个对象的多种状态

比如:

教师 a =老钟;

员工 b= 老钟;

2.多态体现

(1)Father

非静态成员变量x

静态成员变量y

非静态方法eat,方法体输出父类信息

静态方法speak();方法体输出父类信息

(2)Son

非静态成员变量x

静态成员变量y

非静态方法eat,方法体输出子类信息

静态方法speak();方法体输出子类信息

[java] view plain copy
 print?
  1. class Father {  
  2.     int x = 1;  
  3.     static int y = 2;  
  4.   
  5.     void eat() {  
  6.         System.out.println("开吃");  
  7.     }  
  8.   
  9.     static void speak() {  
  10.         System.out.println("小头爸爸");  
  11.     }  
  12. }  
  13.   
  14. class Son extends Father {  
  15.     int x = 3;  
  16.     static int y = 4;  
  17.   
  18.     void eat() {  
  19.         System.out.println("大头儿子很能吃");  
  20.     }  
  21.   
  22.     static void speak() {  
  23.         System.out.println("大头儿子。");  
  24.     }  
  25. }  
  26.   
  27. class Demo {  
  28.   
  29.     public static void main(String[] args) {  
  30.   
  31.         Father f = new Son(); // 父类引用指向了子类对象。  
  32.         System.out.println(f.x);   
  33.         System.out.println(f.y);   
  34.   
  35.         f.eat();   
  36.           
  37.         f.speak();   
  38.           
  39.     }  
  40. }  

Son类继承父类

1:创建Father f=new Son();

这就是父类引用指向了子类对象。

想想下列问题:

f.x=?(非静态)   --1

f.y=?(静态)     --2

f.eat()输出的是子类还是父类信息?(非静态)----子类

f.speak()输出的是子类还是父类信息?(静态)----父类

运行效果如图:


那为什么会有这样的结果呢?看下面的总结~

3.总结:

(1)当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量

(2)当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量

所以:父类和子类有相同的成员变量,多态下访问的是父类的成员变量。

(3)当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。

(4)当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。

4.多态体现-总结:

(1)父类引用变量指向了子类的对象

(2)父类引用也可以接受自己的子类对象

5.多态前提:

类与类之间有关系,继承或者实现

6.多态弊端

提高扩展性,但是只能使用父类引用指向父类成员。

7.多态特点

非静态

(1)编译时期,参考引用型变量所属的类是否有调用的方法,如果有编译通过。没有编译失败

(2)运行时期,参考对象所属类中是否有调用的方法。

(3)总之成员函数在多态调用时,编译看左边,运行看右边。

在多态中,成员变量的特点,无论编译和运行参考左边(引用型变量所属的类)。

在多态中,静态成员函数特点,无论编译和运行都参考左边

8.多态的作用

(1)多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。

[java] view plain copy
 print?
  1.   /*    1:定义功能,根据输出任何图形的面积和周长。 
  2.         子类重写了父类的抽象方法,多态下,会执行子类的非静态方法。 
  3.     2:多态可以作为返回值类型。 
  4.         获取任意一辆车对象 
  5.     3:抽象类和接口都可以作为多态中的父类引用类型。 
  6. */  
  7. abstract class MyShape{  
  8.     public abstract double getArea();  
  9.     public abstract double getLen();  
  10. }  
  11. class  Rect extends MyShape{  
  12.     double width ;  
  13.     double height;  
  14.     Rect(){  
  15.       
  16.     }  
  17.     Rect(double width ,double height){  
  18.         this.width=width;  
  19.         this.height=height;  
  20.     }  
  21.     public double getArea(){  
  22.         return width*height;  
  23.     }  
  24.     public  double getLen(){  
  25.         return 2*(width+height);  
  26.     }  
  27.       
  28. }  
  29. class Circle extends MyShape{  
  30.      double r;  
  31.      public static final double PI=3.14;  
  32.        
  33.      Circle(){  
  34.        
  35.      }  
  36.        
  37.     Circle(double r){  
  38.         this.r=r;  
  39.      }  
  40.     public double getLen(){  
  41.         return 2*PI*r;  
  42.      }  
  43.       
  44.     public double getArea(){  
  45.         return PI*r*r;  
  46.      }  
  47. }  
  48.   
  49. class Demo{  
  50.   
  51.     public static void main(String[] args){  
  52.   
  53.         System.out.println();  
  54.           
  55.         print(new Rect(3,4)); //MyShape m =new Rect(3,4);  
  56.           
  57.         print(new Circle(3));  
  58.           
  59.         }  
  60.           
  61.         //根据用户传入的图形对象,计算出该图形的面积和周长  
  62.         //1:多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。   
  63.         public static void print(MyShape m){    
  64.             System.out.println(m.getLen());  
  65.             System.out.println(m.getArea());  
  66.         }         
  67. }  
效果图:


(2)多态可以作为返回值类型

[java] view plain copy
 print?
  1. /*获取任意一辆车对象 
  2.  1:定义汽车类,有名字和颜色,提供有参和无参构造,有运行的行为。 
  3.  2:定义Bmw类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 
  4.  3:定义Benz类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 
  5.  4:定义Bsj类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 
  6.  5:定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。 
  7.  1:使用(int)Math.round(Math.random()*2); 生成0-2之间随机数。 
  8.  Math 类 
  9.  2:使用if else 判断,指定,0,1,2 new 不同汽车 并返回。 
  10.  6:调用该方法,发现多态的好处。 
  11.  */  
  12. class Car {  
  13.     String name;  
  14.     String color;  
  15.   
  16.     Car() {  
  17.   
  18.     }  
  19.   
  20.     Car(String name, String color) {  
  21.         this.name = name;  
  22.         this.color = color;  
  23.     }  
  24.   
  25.     void run() {  
  26.         System.out.println("跑跑。。。。");  
  27.     }  
  28. }  
  29.   
  30. class Bmw extends Car {  
  31.     Bmw() {  
  32.   
  33.     }  
  34.   
  35.     Bmw(String name, String color) {  
  36.         super(name, color);  
  37.     }  
  38.   
  39.     void run() {  
  40.         System.out.println("宝马很拉风。。。。");  
  41.     }  
  42. }  
  43.   
  44. class Benz extends Car {  
  45.     Benz() {  
  46.   
  47.     }  
  48.   
  49.     Benz(String name, String color) {  
  50.         super(name, color);  
  51.     }  
  52.   
  53.     void run() {  
  54.         System.out.println("奔驰商务首选。。。。");  
  55.     }  
  56. }  
  57.   
  58. class Bsj extends Car {  
  59.   
  60.     Bsj() {  
  61.   
  62.     }  
  63.   
  64.     Bsj(String name, String color) {  
  65.         super(name, color);  
  66.     }  
  67.   
  68.     void run() {  
  69.         System.out.println("泡妞首选。。。。");  
  70.     }  
  71. }  
  72.   
  73. class Demo {  
  74.   
  75.     public static void main(String[] args) {  
  76.   
  77.         int x = 0;  
  78.         while (x < 100) {  
  79.             Car c = CarFactory();  
  80.             c.run();  
  81.             x++;  
  82.         }  
  83.   
  84.     }  
  85.   
  86.     // 定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。  
  87.     // 使用随机数,0.1.2 if 0 bsj 1 bmw 2 bc  
  88.     public static Car CarFactory() {  
  89.         int x = (int) Math.round(Math.random() * 2);  
  90.   
  91.         if (0 == x) {  
  92.             return new Bmw("宝马x6""红色");  
  93.         } else if (1 == x) {  
  94.             return new Benz("奔驰""黑色");  
  95.         } else if (2 == x) {  
  96.             return new Bsj("保时捷""棕色");  
  97.         } else {  
  98.             return new Benz("Smart""红色");  
  99.         }  
  100.   
  101.     }  
  102. }  
效果图:

(3)抽象类和接口都可以作为多态中的父类引用类型。

看第一个作用的例子~

9.多态类型转换

如何在多态下,使用父类引用调用子类特有方法。

(1)基本类型转换:

自动:小->

强制:大->

(2)类类型转换

前提:继承,必须有关系

自动:子类转父类

强转:父类转子类

[java] view plain copy
 print?
  1. class Father {  
  2.   
  3.     void method1() {  
  4.         System.out.println("这是父类1");  
  5.     }  
  6.   
  7.     void method2() {  
  8.         System.out.println("这是父类2");  
  9.     }  
  10. }  
  11.   
  12. class Son extends Father {  
  13.     void method1() {  
  14.         System.out.println("这是子类1");  
  15.     }  
  16.   
  17.     void method3() {  
  18.         System.out.println("这是子类3");  
  19.     }  
  20. }  
  21.   
  22. class Demo {  
  23.   
  24.     public static void main(String[] args) {  
  25.         Father f = new Son();  
  26.         f.method1(); // 这是子类1  
  27.         f.method2(); // 这是父类2  
  28.   
  29.         // f.method3(); //编译报错。  
  30.         // 多态弊端,只能使用父类引用指向父类成员。  
  31.   
  32.         // 类类型转换  
  33.         Son s = (Son) f;  
  34.         s.method3();  
  35.   
  36.         System.out.println();  
  37.     }  
  38. }  
效果图:



好了,多态就写完了~

原创粉丝点击