父类名 引用 = new 子类名()与 子类名 引用 = new 子类名()有什么区别啊?
class Father {
public String s() {
return "Father ";
}
public void show() {
System.out.print(this.s()); // this代表子类对象?
}
}
class Son extends Father {
public String s() { // 复写了父类同名方法
return "Son ";
}
}
class Test
{
public static void main(String args [])
{
Father s = new Son(); // 改成Son s = new Son();有什么区别啊
s.show();
System.out.println();
}
}
我运行的时候怎么不管怎么改方法,结果都是一样的。既然是这样的,那为什么还要用 Father s= new Son();
到底有没有新的用意 啊。。麻烦高手指点。。谢谢了哦
[解决办法]
运行结果当然是打印出son了。
因为你这个对象是用Son类进行实例化的,相应的这个对象调用的也是Son类中的代码。
但是关于你说的父类名 引用 = new 子类名()这个问题,当你这样定义后,你这个对象就只能作为父类对象使用了(虽然它中的代码是执行子类的代码),比如:
class Father {
public String s() {
return "Father ";
}
public void show() {
System.out.print(s()); // this代表子类对象?
}
}
class Son extends Father {
public String s() { // 复写了父类同名方法
return "Son ";
}
public String subS()
{
return "child ";
}
}
public class Test
{
public static void main(String args [])
{
Father s = new Son(); // 改成Son s = new Son();有什么区别啊
System.out.println(s.subS());
s.show();
System.out.println();
}
}
这个时候编辑就会产生一个
找不到符号 subS()的编译错误(虽然我们是Son实例化的,并且可以肯定的是这个对象中有这个方法),这个时候对象已经被用作Father类的对象对待了,而Father类是没有subS()方法的。
这种方式明显的好处就是我可以把所有一类对象(不是一个,这一类对象中有共同的特点,但是有一些具体的信息是不一样的)同意方式处理,而不用关心这个对象是这一类中的哪个,比如我现在就想得到一个人一顿吃几碗饭,但是人分男女、大小、老幼,各种情况不一样,
那么我就写一个通用方法来返回人的饭量
public eatNum(Person p)
{
return p.getNum();
}
而我调用的时候可能p是大人、小孩、老人、女人等等,但是我都作为Person调用,这个时候你就可以实现任意多种人,每种人的getNum都返回特定的数字,而不管你有多少种人,eatNum都可以不变。
[解决办法]
关注
[解决办法]
这段程序是 告诉你 java 有多态 存在
你可以看看这个帖子,他的问题和你一样:
<求助> 小弟刚学,关于多态的问题,大哥们讲解下
System.out.print(this.s()); // this代表子类对象? this 这个关键字就是自生的意思,
谁使用他,他就掉用谁的自身
public String s() // 复写了父类同名方法 这里是重写
下面是你自己的程序 仔细看 ,我什么都不改
class Father {
public String s() {
return "Father ";
}
public void show() {
System.out.print(this.s());
}
}
class Son extends Father {
public String s() {
return "Son ";
}
}
class Test
{
public static void main(String args [])
{
Father s = new Son(); // 改成Son s = new Son();有什么区别啊 回答:没区别
// 你把这里改成 Father s = new Father();
// 回输出 Father;
//看了我上面回的 仔细想象
// Father s = new Son(); 为什么会输出Son
//而Father s = new Father(); 输出 Father
//这就是程序的用意
s.show();
System.out.println();
}
}
[解决办法]
有区别,而且区别很大。如:
父类有public方法 func1(), func2(), func3();
子类继承的父类的这三个方法,此外,子类还新增加了public方法 func4(), func5();
Son s = new Son(); 些时,s 可以调用func1(), func2(), func3(), func4(), func5()这五个方法.
但Father s = new Son(); 这时 s 只能调用父类定义的那几个方法 func1(), func2(), func3(),子类扩展的方法 func4(), func5(),这二个方法s些时是不能调用的,即子类扩展的方法对于父类类型的引用是不可见的。
[解决办法]
这个概念一直不在乎,到现在也没用到过,今天才明白,哈哈 谢谢~~~~~~~~~`
有点工厂模式的味道!!!
[解决办法]
在这里没有区别,不过它体现了针对抽象编程的思想,以父类声明的变量可以通过它的任何一个子类实例化,所以我们可以不需要关心具体子类的实现,增加了灵活性,当然在这里是声明的时候直接实例化的,所以上面提到的灵活性在这里体现不出来,但如果Father s中的变量s的值是通过方法的参数传递进去的话就可以看出来了,这时候我们可以传递Father的任意一个子类的实例
[解决办法]
)在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:
1)实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的。
2)静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。
3)成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。