多态基础
多态是指同一个行为,不同的子类表现出来不同的形式或形态。多态跟属性无关,多态指的是方法的多态,而不是属性的多态。下面参考一个案例:
public class Animal {
public void shout(){
System.out.println("叫。。。");
}
}
public class Cat extends Animal{
public void shout(){
System.out.println("喵喵叫");
}
public void scratch(){
System.out.println("挠人");
}
}
public class Dog extends Animal{
public void shout(){
System.out.println("汪汪叫");
}
public void guard(){
System.out.println("看家护院");
}
}
public class Pig extends Animal{
public void shout(){
System.out.println("哼哼叫");
}
public void eat(){
System.out.println("吃东西");
}
}
public class Girl {
public void play(Animal an){
an.shout();
}
}
public class Test {
public static void main(String[] args) {
Girl g = new Girl();
Pig p = new Pig();
Animal an = p;
g.play(an);
}
}
上面的代码,是多态的一种非常常见的应用场合:父类当方法的形参,然后传入的是具体的子类的对象,然后调用同一个方法,根据传入的子类的不同展现出来的效果也不同,构成了多态。
多态的要素:
-
继承
-
重写
-
父类引用指向子类对象
Pig p = new Pig(); Animal an = p;
上面代码合为一句是:
Animal an = new Pig();
等号左侧是编译器的类型,等号右侧是运行期的类型。
多态的好处:提高了代码的扩展性,符合面向对象的设计原则:开闭原则(扩展是开放的,修改是关闭的)。
向上转型和向下转型
public class Animal {
int age;
public void shout(){
System.out.println("叫。。。");
}
}
public class Pig extends Animal{
double weight;
public void shout(){
System.out.println("哼哼叫");
}
public void eat(){
System.out.println("吃东西");
}
}
public class Test {
public static void main(String[] args) {
Pig p = new Pig();
Animal an = p;
an.shout();
// an.eat(); 报错
an.age = 10;
// an.weight = 60.8; 报错
}
}
上述代码中,有两行报错语句被注释掉了。之所以会报错是因为,对象 an
在编译期是 Animal
类型,而 Animal
类是没有 weight
属性和 eat()
方法的,它们都在 pig
类中。
如果一定要访问 weight
属性和 eat()
方法的话,就要将对象 an
向下转型:
public class Test {
public static void main(String[] args) {
Pig p = new Pig();
Animal an = p; //向上转型
an.shout();
Pig pig = (Pig)an; //向下转型
pig.eat();
pig.age = 10;
pig.weight = 60.8;
}
}
在这里可以想起之前重写 euqals()
方法时的代码,也使用了向下转型:
public boolean equals(Object obj) { //Object obj = new Phone();
Phone other = (Phone)obj; //向下转型
if(this.getBrand()==other.getBrand()&&this.getPrice()==other.getPrice()&&this.getYear()==other.getYear()){
return true;
}
return false;
}