发布网友 发布时间:2022-04-23 13:32
共5个回答
热心网友 时间:2023-08-02 22:22
这是java多态性的表现,要深入理解的话得从内存方面去思考,创建的是子类对象,但是指针类型是父类的,它能指向的内存块是父类应能对应的内容。当你把A类得Area()方法删除时,a指向的内存块里没有Area方法,或者说它指向的这个对象虽然有这个方法,但是这个指针却是没法去访问该方法的, 所以出现无法访问的情况。
然后是a.name=3这个问题,这是由于直接访问成员变量的话 指针指向的任然是父类成员变量,这点记住就行,实际中一般都设getName()、setName()方法进行访问和设置,把name设为private,这样才符合面向对象封装特性,你可以试一下,a.getName()的结果肯定是4
另外父类转化为子类的问题,父类转化为子类不是一定可行的,父类要想转化为子类,其指向的内存块的内容一定要大于等于子类,(即指向对象一定要是子类或者子类的子类。。。)
比如:
A a = new C();
此时把a强制转换为子类是正确的
而A a = new A();
此时把a强制转换为子类则会出错
希望对你有帮助,有不明白的地方可以再问我追问另外我想问下,在父类有一个抽象方法。
public abstract double calcArea();
然后我在子类重写他,
public float calcArea(){}
为什么这样也可以?不是说你重写一个方法,返回值必须要一模一样吗,为什么呢?
难道说仅仅只是抽象的可以?
那我声明普通 double calcArea(){},重写的时候可以float calcArea(){} 吗?
热心网友 时间:2023-08-02 22:23
我说说的理解,不对别见怪哈。
首先A a = new C();这条语句利用了java中的多态特性,即子类对象可以当做父类对象来看。
但是,若我们把子类对象当做父类对象来看是,那么就只能访问父类已有定义的属性和方法,不能访问子类扩展的属性和方法。要是子类把父类的方法覆盖了,再把子类对象的当做父类对象来看,去调用方法,调用的是覆盖后的方法(子类中定义的方法)。
还有就是关于name=3的问题。要记住java中只有在普通的方法中才能表现出多态特性,变量是没有多态存在的,所以是不会输出name = 4.
至于类的转换:
引用类型转换(是引用变量的类型的转换!)
1 向下转型(自动类型转换),是小类型到大类型的转换
如:
Circle c = new Circle(1,2,3);
Shape s = c;//表示圆一定是图形
2 向上造型(强制类型转换),是大类型到小类型。
如:
Shape s = new Circle(1,2,3);
Cirlcle c = (Circle)s; //当s实际引用圆时候,能够转换成功
s = new Rectangle(1,1,2,2);
Circle c2 = (Circle) s;//出现类型转换异常,因为
// s引用的是Rectangle 不是圆实例。
3 instanceof 运算符,用来检查引用对象的类型。
经常与“引用类型强制转换”配合,实现安全的类型换,
避免类型转换异常。
如你例子中的就是向下转型,也就是多态,若果要父类转成子类,就是向上转型,这要 承担出异常的后果,所以转换前要用instanceof判断该父类是否是子类的实例才可。
这些都是我以前的一些笔记,希望能对你有点帮助。
热心网友 时间:2023-08-02 22:23
当你使用A a = new C();的时候其实你声明的是一个A类只是你使用了C类去实体化他。那么A类在这里就有点像接口。你在C类中你重载了area()方法。所以你调用a.area()时就是C类中的内容。但是你的A类中的name属性你没有提供get和set方法并且int name = 3;这种方法将会使其默认为私有方式保存。虽然你在C类中使用了同样的声明int name = 4;但是虽然这两个属性其属性名相同但是他们指向不同的地址。事实上说是不同的变量。当你使用A.name调用属性时,由于声明时你声明的是A类那么它自然访问A类中的name属性。
当你使用C c = new C();的时候其实你声明的是一个C类你又使用了C类去实体化他。那么当你使用c.name时你访问的自然就是C类中的name属性了。
还有当你把A类中的area()方法删去但是A类中保留时。如果你使用如下的声明方式:
A a = new C();那么你声明了一个A类而且你使用C类去实体化他。因为A类中没有area()方法所以C类中的area()方法不会去实体化到这个声明中去(这有点像接口,你实例化接口也是一样的)。所以你调用a.area()自然会报错。因为A类没有这个方法。哪怕C类有这个方法你用C类去实体化也不会实体化这个方法的。
热心网友 时间:2023-08-02 22:24
父类实体永远不可能转换成子类引用成功。
父类引用的实体本身是子类实例时能转换为子类引用。
子类实体可以用父类类型引用,也可以用子类本身类型引用。
父类实体只能用本身类型引用,除非该父类又是另一个类的子类。
子类拥有比父类多的功能,功能多的转换为功能少的可以,但是功能少的要转换为功能多的那是不可能的,因为它根本不具备某些方法。
子类和父类转换这句话应该说成是 子类实体(父类实体)转换为父类引用(子类引用)。
热心网友 时间:2023-08-02 22:24
其实这是JAVA特性之一:多态。A a = new C()中编译的时候是编译A类,运行时运行C类,由于你用a.area()调用了area()方法,而子类C覆盖了该方法,因此会输出c类方法。还有,JAVA多态只适用于方法,与成员变量无关,推荐你看李刚的《疯狂的JAVA讲义》