注册两个月了,散分.写了点java中比较容易混淆的东西,欢迎大家排砖.
初学者甚至老手都容易混淆的问题
1.关于继承
继承有几个比较典型的问题:
a.子类可以继承父类的一切属性和方法。父类中声明为private的method或者field,创建子类的对象之后,父类中定义的field都会在子类的对象中占据空间,也就是分配内存。只是有的属性子类可以直接访问,有的必须通过父类提供的public或者protected方法来访问。private只是声明可见性,你看不到不等于不存在。
b.方法可以覆盖,但是field不可以。Fields cannot be overridden; they can only be hidden.
如果子类中定义了和父类同名的属性,父类中定义的属性可以通过super来访问。
c.private的方法不能被覆盖,但是你可以在子类中重新定义一个和父类中的方法签名相同的方法,这不是覆盖,因为子类是看不到父类中的private方法的。
d.Static members within a class whether fields or methods cannot be overridden, they are always hidden.
2.关于方法调用时的值传递
这个问题已经争论了好多次了,简单的引用一下书里的说法。
Core Java:The term call by value means that the method gets just the value that the caller provides. In contrast, call by reference means that the method gets the location of the variable that the caller provides. Thus, a method can modify the value stored in a variable that is passed by reference but not in one that is passed by value. The Java programming language always uses call by value. That means that the method gets a copy of all parameter values.
The Java Programming Language:All parameters to methods are passed "by value." In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments.You should note that when the parameter is an object reference, it is the object reference not the object itselfthat is passed "by value."
The Java Tutorials:Primitive arguments, such as an int or a double, are passed into methods by value.Reference data type parameters, such as objects, are also passed into methods by value.
sun的很多认证材料上的说法也是pass by value.
大家可以在google中搜一下java ,pass by reference,看看结果
很多人坚持pass by reference的说法,一直也不知道这个术语是谁提出来的。希望专家指正来源。
3.关于重载和多态
多态是面向对象的特性之一,理解也不是特别困难,但是最近发现很多人喜欢把多态和覆盖(Overriding,暂且这么翻译吧)搅在一起。其实自己刚开始学的时候也曾经有过困惑,什么叫做重载(Overloading),什么叫做覆盖(Overriding),后来看书多了也就慢慢理解了,大体的总结一下: 重载是方法之间的一种关系,多个方法使用相同的方法名,但是签名不同,所以我们可以通过签名来区分。早期的java中因为没有采用模板机制,所以大量的方法都是采用重载的方法写成的,比如最经典的System.out.println();在代码里有十种实现方法,接受各种不同类型的参数。这是 Overloading。
覆盖是类层次结构中的一种关系,比如父类有某个方法,子类中同样实现一个同名并且签名相同的方法,这种情况我们称之为overriding。注意,这里要求签名相同。但是返回值可以有些许不同,这里的不同指的是子类中重写的方法可以返回父类中返回类型的子类型,说起来很绕,简单的举个例子,如果父类中方法的返回类型是Number类型,那么子类中的这个覆盖方法的返回类型可以是Number类型,也可以是其子类型,比如Integer,Double等等。
这样两个概念的区别已经很明了了,而且也应该知道,覆盖是实现多态的关键技术。
两个概念还有个重要的区别是,重载是静态绑定的,因为编译的时候编译器就可以根据签名确定具体要调用的方法,而覆盖是运行时绑定的,因为运行的时候才能根据运行时类型信息,确定具体要调用哪个类中定义的覆盖方法。这里面其实有方法表的概念,具体可以参考Core Java.
最后,引经据典,配合一下自己的说法。
《The Java Programming Language》中:
Overloading a method is what you have already learned: providing more than one method with the same name but with different signatures to distinguish them.
Overriding a method means replacing the superclass's implementation of a method with one of your own. The signatures must be identicalbut the return type can vary in a particular way, as discussed below.
初学者甚至老手都容易混淆的问题
1.关于继承
继承有几个比较典型的问题:
a.子类可以继承父类的一切属性和方法。父类中声明为private的method或者field,创建子类的对象之后,父类中定义的field都会在子类的对象中占据空间,也就是分配内存。只是有的属性子类可以直接访问,有的必须通过父类提供的public或者protected方法来访问。private只是声明可见性,你看不到不等于不存在。
b.方法可以覆盖,但是field不可以。Fields cannot be overridden; they can only be hidden.
如果子类中定义了和父类同名的属性,父类中定义的属性可以通过super来访问。
c.private的方法不能被覆盖,但是你可以在子类中重新定义一个和父类中的方法签名相同的方法,这不是覆盖,因为子类是看不到父类中的private方法的。
d.Static members within a class whether fields or methods cannot be overridden, they are always hidden.
2.关于方法调用时的值传递
这个问题已经争论了好多次了,简单的引用一下书里的说法。
Core Java:The term call by value means that the method gets just the value that the caller provides. In contrast, call by reference means that the method gets the location of the variable that the caller provides. Thus, a method can modify the value stored in a variable that is passed by reference but not in one that is passed by value. The Java programming language always uses call by value. That means that the method gets a copy of all parameter values.
The Java Programming Language:All parameters to methods are passed "by value." In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments.You should note that when the parameter is an object reference, it is the object reference not the object itselfthat is passed "by value."
The Java Tutorials:Primitive arguments, such as an int or a double, are passed into methods by value.Reference data type parameters, such as objects, are also passed into methods by value.
sun的很多认证材料上的说法也是pass by value.
大家可以在google中搜一下java ,pass by reference,看看结果
很多人坚持pass by reference的说法,一直也不知道这个术语是谁提出来的。希望专家指正来源。
3.关于重载和多态
多态是面向对象的特性之一,理解也不是特别困难,但是最近发现很多人喜欢把多态和覆盖(Overriding,暂且这么翻译吧)搅在一起。其实自己刚开始学的时候也曾经有过困惑,什么叫做重载(Overloading),什么叫做覆盖(Overriding),后来看书多了也就慢慢理解了,大体的总结一下: 重载是方法之间的一种关系,多个方法使用相同的方法名,但是签名不同,所以我们可以通过签名来区分。早期的java中因为没有采用模板机制,所以大量的方法都是采用重载的方法写成的,比如最经典的System.out.println();在代码里有十种实现方法,接受各种不同类型的参数。这是 Overloading。
覆盖是类层次结构中的一种关系,比如父类有某个方法,子类中同样实现一个同名并且签名相同的方法,这种情况我们称之为overriding。注意,这里要求签名相同。但是返回值可以有些许不同,这里的不同指的是子类中重写的方法可以返回父类中返回类型的子类型,说起来很绕,简单的举个例子,如果父类中方法的返回类型是Number类型,那么子类中的这个覆盖方法的返回类型可以是Number类型,也可以是其子类型,比如Integer,Double等等。
这样两个概念的区别已经很明了了,而且也应该知道,覆盖是实现多态的关键技术。
两个概念还有个重要的区别是,重载是静态绑定的,因为编译的时候编译器就可以根据签名确定具体要调用的方法,而覆盖是运行时绑定的,因为运行的时候才能根据运行时类型信息,确定具体要调用哪个类中定义的覆盖方法。这里面其实有方法表的概念,具体可以参考Core Java.
最后,引经据典,配合一下自己的说法。
《The Java Programming Language》中:
Overloading a method is what you have already learned: providing more than one method with the same name but with different signatures to distinguish them.
Overriding a method means replacing the superclass's implementation of a method with one of your own. The signatures must be identicalbut the return type can vary in a particular way, as discussed below.
解决方案 »
- 关于JTabbedPane没有关闭按钮的问题
- 关于类路径的问题?
- 一个高职教师的问题
- netbeans打开后就自己关闭了~~,大概是因为一次非正常关闭!可是重装后怎么还是不行呀,help~~
- 一个超连接问题,请大家帮忙!先谢谢了!
- Eclipse不让用了,启动的时候出现以下错误,帮忙看看怎么会事!
- 如何清空系统剪切板的内容?
- 谁玩过httpclient》为什么这段简单的代码验证码是空白的!
- jbuilder中文字体乱码
- Applet小应用程序为何在IE中运行不起来?
- 大项目说eclipse不适合做,还是netbeans 好???????放在基础类里调查比较公平
- 一个链表的题,搞不出来了。求大家帮忙!!
1.a子类可以继承父类的一切属性和方法?
如果private的method可以继承的的话,为什么不可以overriding?
2.pass by reference
class Ob {
private int t = 0;
public Ob(int i){
t = i;
}
public int getT(){
return t;
}
public void setT(int i){
t = i;
}
}public class Test {
public static void change(Ob o, int t){
o.setT(t);
}
public static void main(String[] args){
Ob b = new Ob(8);
Test.change(b, 4);
System.out.print(b.getT());
}
}
输出是4,那不是by reference吗?
喜欢把它理解成pass by the copy of the object
Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level.For example, consider a method in an arbitrary class that moves Circle objects: public void moveCircle(Circle circle, int deltaX, int deltaY) {
// code to move origin of circle to x+deltaX, y+deltaY
circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);
//code to assign a new reference to circle
circle = new Circle(0, 0);
}Let the method be invoked with these arguments: moveCircle(myCircle, 23, 56)Inside the method, circle initially refers to myCircle. The method changes the x and y coordinates of the object that circle references (i.e., myCircle) by 23 and 56, respectively. These changes will persist when the method returns. Then circle is assigned a reference to a new Circle object with x = y = 0. This reassignment has no permanence, however, because the reference was passed in by value and cannot change. Within the method, the object pointed to by circle has changed, but, when the method returns, myCircle still references the same Circle object as before the method was called.
Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory. If the Java programming language actually had pass-by-reference parameters, there would be a way to declare halveIt so that the above code would modify the value of one, or so that commonName could change the variable sirius to null. This is not possible. The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing modepass by valueand that helps keep things simple.
ibm社区的一个文档,大家可以看看.
8种基本类型肯定是value传递,对于对象类型,传进去reference的时候,方法会将这个reference复制一份而并不是
直接使用它,每一个reference也有值的,就是它所对应的对象在堆中的地址,方法将这个值接收然后赋给了方法中的局部变量,
这大概才是值传递的本意。
------一个菜鸟的见解
如果debug跟踪,method内部与外部在堆中的地址也都是一样的
http://www.racecareer.com/search-nr.asp?id=269日语PL(JAVA 开发方向)http://www.racecareer.com/search-nr.asp?id=294
如果点击无效 ,请将链接复制到地址栏[email protected]
Tina:88122571
MOB:138 8946 0104
借用一切皆是对象的思想,这里也可以说一切都是值。reference也是可以做为值来传递的。个人认为如果是在C++里就不会有这种争辩,因为指针弄得通,这个就是小问题,说白了所谓的reference传递,也就是传地址。
反正我是这么理解的,请更正
从java语言的设计哲学来说为了简化都设计为值传递了,而且我看到的资料都是这个说法.
看来该重新设计java语言了,真无聊.
到中国就不一样了.
对于一个developer来说(至少是我吧),不管是copy,
还是真reference,都是'reference'(因为都指向了一个Object,而非value)
这样,我在develop的时候,知道参数在函数内部是可以被改变的。
Core Java中说这么清楚了,连什么是pass by reference都说清楚了,还有什么好讨论的,呵呵曾经在http://www.cjsdn.net/post/view?bid=1&id=195048&sty=1&tpg=1&age=0参加过讨论,没读过知道Core Java,只是自己直观的理解,说服力不强,郁闷!
There is exactly one parameter passing modepass by valueand that helps keep things simple.
当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
对象和引用型变量被当作参数传递给方法时,在方法实体中,无法给原变量重新赋值,但是可以改变它所指向对象的属性。至于到底它是值传递还是引用传递,这并不重要,重要的是我们要清楚当一个引用被作为参数传递给一个方法时,在这个方法体内会发生什么。 我来具体谈一谈,方法重载与方法重写的区别:
方法重载
在Java中,如果要在同一个类中写多个相同的名字的方法,那么只需要这些方法的参数不同就行.这个过程称为方法重载.方法重载是多态性的一种,也是Java的特征之一.所谓多态性,是指可以向功能传递不同的消息,以便让对象根据相应的消息来产生一定的行为.对象的功能通过类中的方法来实现,那么功能的多态性就是方法的重载.
方法重载可以概括为一句话:同名不同参.不同参可以是指不同类型的参数,也可以是参数的数量不同.其中方法的返回类型及参数的名字与之无关.例如:Class A{
void test(){}
int test(){} //非法,因为方法重载与返回类型无关
}方法重写(继承下的重写)
子类可以通过方法重写来隐藏继承父类的方法.方法重写是指,子类中定义了一个方法,并且这个方法的名字、返回类型、参数类型及参数的个数与从父类继承的方法完全相同。通过方法重写,子类就可以把父类的状态和行为变成自己的状态和行为。只要父类的方法能够被子类继承,子类就能重写这个方法。一旦子类重写了这个方法,就表示隐藏了所继承的这个方法。如果子类对象调用这个方法,那也是调用重写后的方法。
来看一个方法重写的例题。
class A{
void smile()
{
System.out.println("我考试得了第一,我很高兴!");
}
void cry()
{
System.out.println("看完这部电影,我感动的哭了...");
}
}class B extends A{
B(){
smile();
cry();
}
void smile()
{
System.out.println("我找到了一份好工作,我太高兴了!")
}
}class RewriteTest{
public static void main(String args[])
{
B b= new B()
}
}
输出结果为:我找到了一份好工作,我太高兴了!
看完这部电影,我感动的哭了
Press any key to continue...
在这个程序中,类B继承类A后,重写了父类的smile()方法。从输出结果我们可以看出父类(类A)的smile()方法中的语句并没有打印出来。
重写方法既可以操作继承的成员变量,也可以操作子类声明定义的成员变量。如果子类想调用被隐藏的方法,必须使用关键字super.
以上是我对重载和重写概念的理解,欢迎各位批评指正。
我看国人的书上有人提出了方法多态的概念,就是指的这个overloading.但这个概念其实跟面向对象一点关系都没有.
我们一提到面向对象,就提到三个特性,继承,多态,信息隐藏.多态可以看作是面向对象的本质特征之一.那方法的重载跟它有什么关系呢?
像C++这样的语言就可以直接定义方法重载而不涉及任何面向对象的东西.
而且方法的overloading是静态绑定的,跟多态那种运行时的表现也有本质的区别.
所以还是不要提这个方法多态的好.
如果子类中定义了和父类同名的属性,父类中定义的属性可以通过super来访问。 对这个不是很理解 :)父类中overriding的method也可以通过super 来访问的