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