Java中的多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态的优点:1、低耦合 2、易扩展 3、可替换性
多态存在的必要条件:继承 重写 父类引用指向子类对象
成员变量的多态性:
编译的时候,参考父类中的成员变量,如果有,编译成功,如果没有,编译失败。
运行的时候,运行的是父类中的变量值。
1 package com.shamgod.polymorphism; 2 /** 3 * 动物父类 4 * @author ShammGod 5 * 6 */ 7 public class Animal { 8 9 String name = "动物"; 10 int age = 10; 11 12 }
1 package com.shamgod.polymorphism; 2 /** 3 * 动物的子类,猪类 4 * @author ShammGod 5 * 6 */ 7 public class Pig extends Animal{ 8 int age = 2; 9 String name = "佩奇"; 10 String color = "pink"; 11 }
1 package com.shamgod.polymorphism; 2 /** 3 * 测试类 4 * @author ShammGod 5 * 6 */ 7 public class TestPolymorphism { 8 public static void main(String[] args) { 9 10 //父类的引用指向子类的对象 11 Animal pig = new Pig(); 12 //编译不通过,父类没有该属性 13 //System.out.println(pig.color); 14 //输出的是父类的成员变量的值 15 System.out.println(pig.name + " " +pig.age);//动物 10 16 } 17 }
成员方法的多态性:
编译的时候,参考父类中的成员方法,如果有,编译成功,如果没有,编译失败。
运行的时候,运行的是子类的方法。
1 package com.shamgod.polymorphism; 2 /** 3 * 动物父类 4 * @author ShammGod 5 * 6 */ 7 public class Animal { 8 9 void say() { 10 System.out.println("I'm an animal!"); 11 } 12 }
package com.shamgod.polymorphism; /** * 动物的子类,猪类 * @author ShammGod * */ public class Pig extends Animal{ /* * 子类自己的成员方法 */ void sayHello() { System.out.println("hello"); } /* * 子类重写父类的方法 */ @Override void say() { // TODO Auto-generated method stub System.out.println("I'm a pig!"); } }
package com.shamgod.polymorphism; /** * 测试类 * @author ShammGod * */ public class TestPolymorphism { public static void main(String[] args) { //父类的引用指向子类的对象 Animal pig = new Pig(); //编译不通过,父类没有该方法 //pig.sayHello(); //调用的是子类的成员方法 pig.say();//I'm a pig! } }
静态变量的多态性(一般类变量直接使用类名调用即可,该例子只演示,实际没有人这么用,静态变量属于类,不属于对象):
编译的时候,参考父类中的静态变量,如果有,编译成功,如果没有,编译失败。
运行的时候,运行的是父类中的静态变量值。
1 package com.shamgod.polymorphism; 2 /** 3 * 动物父类 4 * @author ShammGod 5 * 6 */ 7 public class Animal { 8 //父类静态变量 9 static String name = "animal"; 10 }
1 package com.shamgod.polymorphism; 2 /** 3 * 动物的子类,猪类 4 * @author ShammGod 5 * 6 */ 7 public class Pig extends Animal{ 8 //子类静态变量 9 static String name = "pig"; 10 static int age = 23; 11 }
1 package com.shamgod.polymorphism; 2 /** 3 * 测试类 4 * @author ShammGod 5 * 6 */ 7 public class TestPolymorphism { 8 public static void main(String[] args) { 9 10 //父类的引用指向子类的对象 11 Animal pig = new Pig(); 12 //父类没有该静态变量,编译不通过 13 //System.out.println(pig.age); 14 //输出的是父类的静态变量的值 15 System.out.println(pig.name);//animal 16 } 17 }
静态方法的多态性:
编译的时候,参考父类中的成员方法,如果有,编译成功,如果没有,编译失败
运行的时候,运行的是父类的方法
1 package com.shamgod.polymorphism; 2 /** 3 * 动物父类 4 * @author ShammGod 5 * 6 */ 7 public class Animal { 8 //父类静态方法 9 static void say() { 10 System.out.println("I'm an animal"); 11 } 12 }
1 package com.shamgod.polymorphism; 2 /** 3 * 动物的子类,猪类 4 * @author ShammGod 5 * 6 */ 7 public class Pig extends Animal{ 8 9 //子类重写父类的静态方法 10 static void say() { 11 System.out.println("I'm a pig!"); 12 } 13 //子类自己的静态方法 14 static void sayHello() { 15 System.out.println("Hello!"); 16 } 17 }
1 package com.shamgod.polymorphism; 2 /** 3 * 测试类 4 * @author ShammGod 5 * 6 */ 7 public class TestPolymorphism { 8 public static void main(String[] args) { 9 10 //父类的引用指向子类的对象 11 Animal pig = new Pig(); 12 //父类没有该静态方法,编译不通过 13 //pig.sayHello(); 14 //输出的是父类的静态变量的值 15 pig.say();//I'm an animal 16 } 17 }
总结:首先说一下静态和非静态,static修饰的变量和方法属于类,不属于对象,是共享的,多态的必要条件包括重写,静态方法是不允许被重写的,所以调用一个对象的静态,就是调用该对象的对应的类的方法,不属于多态的范围。还是那句,多态的必要条件是重写,所以不管成员属性还是类属性,都不能算是多态,调用成员变量的时候调用的是父类引用的值,调用静态变量的时候调用的就是该对象所对应的类的静态变量的值。所以在多态的讨论范围中,应该只有成员方法,当父类的引用指向子类的对象时,调用该对象的方法就是调用子类的成员方法,这就是父子类之间的多态。另外还有一种叫重载,属于类内的多态性。这也符合了多态的定义:“多态是同一个行为具有多个不同表现形式或形态的能力”。