抽象类
和抽象类离不开的是抽象方法,由于子类中对同一个方法的实现方式不同,引入了方法和抽象类,比如:
package Chouxianglei;
public class MainDemo {
Animal a=new Cat();
a.eat();
int a=a.age;
}
package Chouxianglei;
public abstract class Animal {
int age=20;
public abstract void eat();
}
package Chouxianglei;
public class Cat extends Animal{
int age=40;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
(1)由于不同的Animal对eat方法的实现不尽相同,我们在抽象类Animal中定义了抽象方法eat,在继承时,子类必须实现父类中的所有抽象方法,除非子类也是抽象类
(2)抽象类不能直接实例化,我们只能通过子类来进行间接实例化,所以我们定义了变量a,a的引用是Animal类但其被实例化为Cat,对于a.eat();语句,程序会直接运行eat方法在子类Cat中的重载,对于a.age,由于a的引用是Animal类的,引用的地址存在栈中,a的实例化是Cat,存在堆中,程序运行时是无法直接访问堆内存的,也就无法访问堆内存中Cat类里面的age(因为程序直接访问的时栈内存,而栈中并不存有Cat类中age的引用),所以a.age访问的是Animal里面的age成员。(这里有点不好理解)
(3)抽象类在作为参数或返回值进行传递时,本质上传递的是抽象类的实例化对象,这里很好理解,方法本质上是对具体的东西进行处理,传个引用过去当然不合理啦