1.1多态概念
多态是指同一个对象在不同的时刻代表不同的东西,指的是对象的多种形态。
例如:动物吃的粮食,对狗来说就是狗粮,对猫来说就是猫粮。
同一个事情,对不同的对象会有不一样的结果。
1.2多态实现的条件
1.必须在继承类中
2.子类必须对父类中的方法进行重写
3.需要调用重写的方法
//基类——动物
public class Animal {
String name;
int age;
public Animal(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println(name+"在吃东西");
}
}
//子类——狗
public class Dog extends Animal{
public Dog(String name,int age){
super(name,age);
}
@Override
public void eat(){
System.out.println(name+"在吃狗粮");
}
}
//子类——猫
public class Cat extends Animal{
public Cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println(name+"在吃猫粮");
}
}
//实例化调用重写方法
public class TestAnimal {
public static void eat(Animal a){
// 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
// 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
a.eat();
}
public static void main(String[] args) {
Dog dog=new Dog("章章",18);
Cat cat=new Cat("峰峰",19);
dog.eat();
cat.eat();
}
}
输出结果:
1.3重写
1.3.1重写
它是子类对父类中非静态,非私有,未被final修饰以及非构造方法外的方法进行重新编写的一个过程。
要求:返回值和参数都不能改变,仅可改变方法内的内容。
1.3.2重写的规则
1.子类在重写方法时,一般要求与父类中被重写的方法名一样,参数类型一致,返回值类型完全相同。
2.重写方法的返回值类型可以不完全一致,但是必须有父子关系
3.子类重写的方法权限不能比父类中被重写的方法权限低,例如,父类方法的权限是public,子类权限就不能写protected
4.当父类方法是构造方法,被private,final或static修饰后都不能进行重写
5.重写的方法可以使用@Override来检验合法性。
1.4向上转型和向下转型
1.4.1向上转型:
就是创建一个子类对象,将其当作父类对象来使用,从小范围向大范围转换,比如狗是动物,猫是动物,就属于向上转型。
//Animal.java------父类
public class Animal {
protected String name;
int age;
public Animal(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println(name+"在吃东西");
}
public void sleep(){
System.out.println(name+"在睡觉");
}
}
//Cat.java-----子类
public class Cat extends Animal{
public Cat(String name,int age){
super(name,age);
}
@Override
public void eat() {
System.out.println(name+"在吃小鱼干");
}
@Override
public void sleep() {
System.out.println(name+"在睡大觉");
}
}
//Dog.java-----子类
public class Dog extends Animal {
public Dog(String name,int age){
super(name,age);
}
@Override
public void eat() {
System.out.println(name+"在吃狗粮");
}
@Override
public void sleep() {
System.out.println(name+"在呼呼呼");
}
}
public class TestAnimal {
public static void method1(Animal animal){
animal.eat();
animal.sleep();
}
public static Animal buyAnimal(String kind){
if(kind.equals("狗")){
return new Dog("渣渣",20);
} else if (kind.equals("猫")) {
return new Cat("博博",20);
}else{
return null;
}
}
public static void main(String[] args) {
Animal animal1= new Dog("章章", 19);
method1(animal1);
Animal animal2 = new Cat("峰峰", 19);
method1(animal2);
//向上转型,狗是动物,猫是动物,逻辑上合理,编译也可以通过,在实现多态的时候一直采用向上转型
Animal animal3=buyAnimal("猫");
animal3.eat();
animal3.sleep();
}
}
运行结果:
注意:向上转型不能调用子类中的方法
1.4.2向下转型:
将一个子类对象向上转型后无法调用子类方法,但又需要使用子类方法,此时将此对象向下转型,还原成子类对象。
public class TestAnimal {
public static void method(Animal animal){
animal.eat();
animal.sleep();
if(animal instanceof Cat){
Cat cat=(Cat)animal;
cat.sleep();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.sleep();
}
//instanceof判断animal是否属于Dog类的对象,如果是返回true,不是返回false
//如果返回true,就可以对此对象进行强转,实现向下转型,否则编译报错并且无法运行,此时转型不安全。
}
public static void main(String[] args) {
Dog dog=new Dog("章章",18);
Cat cat=new Cat("峰峰",20);
method(dog);
System.out.println("==============");
method(cat);
}
}
注意:向下转型尽量使用Instanceof判断是否可以转型,否则容易发生不安全转型。