猿问

抽象方法是怎么实现子类统一的入口的?父类.对象方法;又不能访问;指向父类方法;方法又是不完整的

如果我把抽象类的抽象方法注释掉了;maxArea()里的.area()会报错;
shapes[0] = new Circle(1);完成向上构造;shapes[0].area();向上构造看引用类型;如果点的父类方法;那是不完整的;如果是指向对象的方法;父类又不能访问子类;
那么shapes[0].area();.的到底是谁的?为什么?抽象方法为什么是子类统一的入口?
请你帮我解释下好吗?

public class ShapeTest {
public static void main(String[] args) {
//Shape s = new Shape(); //编译错误,抽象类不能被实例化
Shape[] shapes = new Shape[4]; //创建Shape数组对象
shapes[0] = new Circle(1);
shapes[1] = new Circle(2); //大
shapes[2] = new Square(1);
shapes[3] = new Square(2);
maxArea(shapes);
}
//求数组的最大面积
public static void maxArea(Shape[] shapes){
double max = shapes[0].area();
int maxIndex = 0; //最大面积下标
for(int i=1;i<shapes.length;i++){
double area = shapes[i].area();
if(area>max){
max=area;
maxIndex=i;
}
}
System.out.println("最大面积为:"+max+",所在下标为:"+maxIndex);
}
}

abstract class Shape{ //抽象类
protected double c; //周长
public abstract double area(); //抽象方法
}
class Circle extends Shape{
public Circle(double c){
super.c = c;
}
public double area(){ //重写抽象方法
return 0.0796*c*c; //0.0625
}
}
class Square extends Shape{
public Square(double c){
super.c = c;
}
public double area(){
return 0.0625*c*c;
}
}

www说
浏览 633回答 4
4回答

呼如林

你父类有的特性派生类肯定有,你子类有的特性父类不一定有。 因此你把父类的特性(方法)去掉,而你申明的又是父类的数组,编译器当然不知道你会塞个什么东西进去,所以会报错咯。 父类不能访问子类这个也正常,你子类可能有自己的特殊性,那么我父类去访问的时候怎么知道这些东西呢?而且在对象构造时子类的构造函数在执行时第一步就是去super父类,那么也就说明了现有父类后有子类,如果能够让父类去访问子类的信息这个就会出现问题(这个时候子类还没完成构造工作)。 shapes[0].area()这个具体是谁的area方法要看你shapes[0]里面是谁了,如果是Circle而且它又override掉了父类的这个方法那就是Circle的了,如果没有override那么就是父类的了。这个解释也很简单,主要是看shapes[0]在运行时是谁,这是面相对象语言本来的特性。 抽象方法是子类的统一入口这个描述不太准确,一个是方法,一个是对象实例,这两个没关系。抽象方法需要在其派生类中去实现,而抽象方法本身仅作为一种契约而已,这个不是这个方法的唯一入口,如果你直接Circle c=new Circle()后还是可以执行这个方法(这个被override方法本来就属于Circle对象)

呼啦一阵风

怎么判断:如果是Circle而且它又override掉了父类的这个方法那就是Circle的了;是引用吗?

素胚勾勒不出你

@小梁丶:  针对这个场景吧。 Shape shape=new Circle(); shape.area(); 这个在实际调用的时候area方法是个虚方法,那么需要根据对象派生关系找到实际调用方法的来源,由于你Circle已经override掉了此方法,而且此处实例化的实例是Circle,那么当然就调用Circle的方法了。
随时随地看视频慕课网APP

相关分类

Java
我要回答