-
java子类继承父类问题10
java子类继承父类问题
求解释! 虽然做了几年的开发
但确实不明白为什么?class Foo { public int a; public Foo() { a = 3; } public void addFive() { a += 5; } } public class Bar extends Foo{ public int a; public Bar() { a = 8; } public void addFive() { this.a +=5; } public static void main(String[] args) { Foo foo = new Bar(); foo.addFive(); System.out.println("Value: "+ foo.a); } }
结果为什么输出的是3
可以试下~
求解释
问题补充:
看到楼下的很多朋友的回答
我之前也是这么认为的
与java得多态有关 方法可以多态重载,但属性不能
假设这样设想 我想得到结果是
在父类的属性a的值的基础上 让其用子类的加法进行呢?
如何实现呢?public int addFive() { super.a += 5; }
就可以了
2009年9月11日 19:51
22个答案 按时间排序 按投票排序
-
采纳的答案
class Foo { public int a; public Foo() { a = 3; } public int addFive() { a += 5; return a; } public int getA() { return a; } } public class Bar extends Foo { public int a; public Bar() { a = 8; } public int addFive() { this.a += 5; return a; } public int getA() { return a; } public static void main(String[] args) { Foo foo = new Bar(); //调用的是子类中的方法 System.out.println(foo.getA()); //直接调用父类中的a System.out.println("Value: " + foo.a); //调用的是子类中的方法 System.out.println(foo.addFive()); } }
输出结果:
8
Value: 3
13
楼主,只需要明白一点就行了:在Java中重写指的是方法的重写,而不是属性的重写,还有多态也只是方法的多态 ,没有属性的多态。
2009年9月14日 09:25
-
class Base{
public int a;
public static int b;
public Base(){
a=1;
b=1;
}
public void addFivetoa(){
a+=5;
}
public static void addSixtob(){
b+=6;
}
}
public class Son extends Base{
//public int a;
//public static int b;
public Son(){
a=2;
b=2;
}
public void addFivetoa(){
a+=5;
}
public static void addSixtob(){
b+=6;
}
public static void main(String args[]){
Son son = new Son();
Base base = son;
base.addFivetoa();
base.addSixtob();
System.out.println(base.a);//7
System.out.println(base.b);//8
System.out.println(son.a);//7
System.out.println(son.b);//8
}
}
过程:先初始化Base的b为0,然后调用父类的构造方法初始化a=1,b=1,然后调用Son的构造方法初始化a=2,b=2;
base.addFivetoa();//a=7;调用的子类的
base.addSixtob();//b=8;调用的父类的
属性是不能多态的,静态方法也不能多态。
图示:
[img] http://dl.iteye.com/upload/attachment/146753/1c112269-254f-3f9e-9bd4-afa547d99cd3.jpg[/img]
衍生:
Java代码
class Base{
public int a;
public static int b;
public Base(){
a=1;
b=1;
}
public void addFivetoa(){
a+=5;
}
public static void addSixtob(){
b+=6;
}
}
public class Son extends Base{
public int a;
public static int b;
public Son(){
a=2;
b=2;
}
public void addFivetoa(){
a+=5;
}
public static void addSixtob(){
b+=6;
}
public static void main(String args[]){
Son son = new Son();
Base base = son;
base.addFivetoa();
base.addSixtob();
System.out.println(base.a);//1
System.out.println(base.b);//7
System.out.println(son.a);//7
System.out.println(son.b);//2
}
}
过程:先初始化Base的b为0,然后调用父类的构造方法初始化a=1,b=1,然后调用Son的构造方法初始化子类中的a和b,a=2,b=2;
base.addFivetoa();//调用子类的方法,son.a=7
base.addSixtob();//调用父类的方法,base.b=1+6=7
剩下的base.a和son.b都没有变化所以分别为1,2。
其中加粗红色的1是父类的b的值,base.addSixtob()(是静态的)所以要调用addSixtob()所在类base的b的值也就是,或者说是base对象调用了addSixtob(),所以要访问base对象所在类的b值。
图示:
2009年9月18日 17:48
-
引用Foo foo = new Bar(); 此时,new的虽然是Bar()的实力,但是在内存看到的只是父类的方法跟属性,与子类无关。所以,a的值为3。
子类的方法,父类的属性2009年9月18日 10:25
-
Foo foo = new Bar(); 此时,new的虽然是Bar()的实力,但是在内存看到的只是父类的方法跟属性,与子类无关。所以,a的值为3。
2009年9月18日 10:23
-
Foo foo = new Bar(); //foo.a=3,bar.a=8 foo.addFive(); //bar.a=8+5 System.out.println("Value: "+ foo.a); //foo.a=3,bar.a=13
这也是隐藏域,提供setter/getter的一个原因吧。2009年9月17日 15:29
-
父类中的a和子类中的a是两个不同的成员变量,同时存在的,不会出现覆盖的现象。
Foo foo = new TestEYE1(); //调用父类构造。
此时,foo虽然是TestEYE1,但是它是被当作Foo来执行的。
所以它的一些TestEYE1属性全部都被禁用。但是堆中存在这些属性。
当调用
foo.addFive(); 方法时,由于子类对父类的方法重写,执行子类的方法,
this.a +=5; 其中this可以不加的,默认的就是调用本类(TestEYE1)的成员变量。
最后打印foo.a,foo虽然有两个a成员变量,但是因为它现在是Foo身份,所以子类的a是禁用的,但是它还是存在的,只要身份变成TestEYE1,就会打印子类的a属性。看第二次打印的结果就知道了。
System.out.println("Value: "+ foo.a);
System.out.println("Value: "+ ((TestEYE1)foo).a);
这个题目,如果楼主觉得混要,有一个简单的方法,把子类的a全改成b,就知道了。
因为对计算机而言,这两个成员变量就算是名字相同,它也认为不同的。
只要明白,这两个成员变量都存在就好理解了~2009年9月16日 13:43
-
注意:这句 Foo foo = new Bar();创建了一个Bar对象
一个对象创建的过程分成4步:
1.分配总空间
2.递归创建父类对象
3.调用本类构造方法
4.初始化本类属性;
还有第2点 其实是创建了父类的属性和方法,并没有创建父类对象,用人们的眼光来把它
单独拿出来看,像是创建了父类对象似的;
父类的除private方法以外的方法都被子类所继承.并且覆盖但是属性却没有被覆盖,所以foo.a 访问的是父类的 属性,而 foo.addFive(); 调用的是子类覆盖父类的 addFive()方法,既然调用的是子类的方法,所以这个方法修改的是子类属性的值
2009年9月14日 22:03
-
引用有点值得关注的是。如果addFive返回类型改成int 之后
你打印System.out.println(foo.addFive());
的值是18,而不是13。
晕。。我用了两次 foo.addFive(); 怪不得是18.
晕到我。2009年9月13日 13:41
-
主要的问题是你要理解子类重写父类方法会造成父类方法被覆盖,而属性却不是这样;
Foo foo = new Bar();
程序运行到这一部,是实例化一个子类对象交给父类引用,在这个对象中有两个属性a,父类的属性a=3和子类自己的a=8 ,而addFive方法只有一个,那就是子类重写的addFive方法;
foo.addFive();
这一步调用的是子类重写后的方法,所以在这里值发生改变的是子类的a而不是父类的,这时候子类的a=8+5=13,而父类的a=3没有变。
System.out.println("Value: "+ foo.a);
foo是一个父类的引用,foo.a是父类的a当然是等于3了2009年9月12日 14:25
-
Foo foo = new Bar();
像这种upcast(向上造型)
1.域:调用父类属性
2.方法:调用子类方法
这里 foo.addFive(); 调用子类的方法
有点值得关注的是。如果addFive返回类型改成int 之后
你打印System.out.println(foo.addFive());
的值是18,而不是13。
至于输出的是3
就是因为第一条,调用的是父类的属性。而跟方法无关。引用详情见:thinking in java 4th 的例子
中文版156
英文版2902009年9月12日 12:25
-
Foo foo = new Bar(); //实际上实例化Foo 类中的a = 3;
foo.addFive(); //实际上调用了Bar类的方法
如果是想得到 5 + 8 = 13的结果,就封装a字段
class Foo {
private int a;
public Foo() { a = 3; }
public void addFive() { a += 5; }
public int getA() {
return a;
}
}
public class Bar extends Foo{
private int a;
public Bar() { a = 8; }
public int getA() {
return a;
}
@Override
public void addFive() { a +=5; }
public static void main(String[] args) {
Foo foo = new Bar();
foo.addFive();
System.out.println("Value: "+ foo.getA());
}
}2009年9月12日 09:12
-
这个是java类初始化问题,每个子类对象都含有父类对象,所以要先调用父类的构造函数构造一个父类对象。
你可以看看:Java类初始化顺序
http://red-xie.iteye.com/admin/blogs/2587892009年9月12日 00:41
相关推荐
Java子类继承父类实例-披萨的选择实现代码 本篇文章主要介绍了Java子类继承父类实例-披萨的选择实现代码,通过编写程序实现比萨制作,选择需要制作的比萨。可供选择的比萨有:培根比萨和海鲜比萨。下面是相关知识点...
在Java编程语言中,子类继承父类是一种常见的特性,它允许子类扩展或复用父类的功能。当我们创建一个子类对象并将其赋值给父类引用时,这种行为被称为向上转型(Upcasting)。这一过程是自动且安全的,因为子类对象...
在Java中,继承是面向对象编程的核心特征之一,它允许我们创建一个新类(子类)基于一个已经存在的类(父类或超类)的结构。这样可以复用现有类的代码,并可添加或覆盖特性来形成新的类。本文将通过具体的代码范例,...
Java 子类重写父类的方法详细解析 Java 中子类重写父类的方法是面向对象编程的核心概念之一。子类可以重写父类的方法,以改变或扩展父类的行为。但是,子类重写父类的方法需要遵守一定的规则,以避免编译器错误和...
在 Java 中,使用 `extends` 关键字可以实现继承关系,子类可以继承父类的属性和方法,并可以重写父类的方法。使用 `super` 关键字可以引用父类的成分,访问父类中定义的属性和方法。 在 Java 中,可以使用多态性来...
当一个子类继承一个父类时,子类就自动获得了父类的所有非私有(public和protected)成员,包括字段和方法。这使得子类能够共享父类的功能,同时还可以添加自己的特性和行为。通过关键字`extends`,我们可以声明一个...
子类B不仅可以继承父类A的所有公有(public)和受保护(protected)成员,还可以有自己的特有成员。当我们声明一个父类类型的引用并将其赋值为子类的对象时,如`Car car = new SportsCar();`,这里的`car`引用虽然...
文章围绕子类继承父类成员的过程、成员变量及方法的赋值、重写、覆盖等问题展开讨论,旨在帮助读者更好地理解Java继承中的重点与难点。 #### 关键词 - 继承机制 - 父类 - 子类 #### 一、超类的属性或方法在继承...
总结,Java反射机制为我们提供了强大的动态性,能够方便地获取和操作类的属性和方法,包括私有成员和子类父类中的成员。通过熟练掌握反射技术,开发者可以实现更灵活、更动态的代码,但也需要谨慎使用,以避免潜在的...
本文将深入探讨在继承中的程序执行顺序,以及子类与父类的执行顺序问题。 首先,我们需要了解Java或Python等面向对象语言中类的构造过程。当一个类实例化时,其构造函数(在Java中是`构造器`,在Python中是`__init_...
Java子类调用父类的方法中包含子类重写的实例方法 Java 子类调用父类的方法中包含子类重写的实例方法是 Java 编程语言中一个重要的概念。下面我们将详细介绍这个概念,包括相关的知识点和示例代码。 子类调用父类...
Java编程关于子类重写父类方法问题的理解 Java编程中,子类重写父类方法是非常重要的概念之一。子类重新实现父类的方法称为重写,重写时可以修改访问权限修饰符和返回值,但方法名和参数类型及个数不能修改。只有...
这个主题涉及到面向对象编程的基本原理,特别是子类继承父类后如何访问和操作子类特有的属性。下面我们将深入探讨这个话题。 首先,我们了解基本的继承概念。在Java中,一个类(子类)可以继承另一个类(父类),...
在本篇文章中,我们学习了如何使用 Java 中的反射机制来判断类的继承关系,包括判断一个类是否为基本数据类型、判断一个类是否为另一个类的子类或父类,以及如何获取泛型类型实例。这些技术在日常开发中非常实用,...
1. 代码重用:继承允许子类继承父类的属性和方法,从而减少代码的冗余和重复。 2. 继承关系建模:继承可以建模现实世界中的继承关系,如车辆的继承关系,即 Car 。 3. 提高代码的灵活性:继承允许子类继承父类的方法...
在Java编程语言中,继承是面向对象编程的一个关键特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。这有助于实现代码重用,并且可以创建层次结构的类系统,使代码更加模块化。下面我们将深入探讨Java中...
如果子类和父类不在同一个包中,那么子类继承了父类的protected、public成员变量作为子类的成员变量,并且继承了父类的protected、public方法,继承的成员或方法的访问权限保持不变,但子类不能继承父类的友好...