我是java编程的新手,也是stackoverflow的新手。请注意这个我无法理解的简单代码。请帮我解决这个问题
class Base {
public static void foo(Base bObj) {
System.out.println("In Base.foo()");
if(bObj instanceof Base){
System.out.println("Base instance");
}
bObj.bar();
}
public void bar() {
System.out.println("In Base.bar()");
}
}
class Derived extends Base {
public static void foo(Base bObj) {
System.out.println("In Derived.foo()");
bObj.bar();
}
public void bar() {
System.out.println("In Derived.bar()");
}
}
class Downcast {
public static void main(String []args) {
Base bObj = new Derived();
bObj.foo(bObj);
}
}
现在我来了
In Base.foo()
Base instance
In Derived.bar()
虽然我得到了它如何base.foo()
。但是如何派生。它还打印出它是一个基础对象的实例然后是如何派生的。给出的解释是早期它做了静态解析,后来又动态了。是静态和动态分辨率。
我虽然概念是
Base b=new Derived();
这意味着我们创建了一个派生对象,然后将其上传到Base.So为什么不调用base.bar()?
提前致谢。
答案 0 :(得分:4)
这是多态性的核心所在。 Java中的对象尝试以与真实对象相同的方式运行。
自行车通常有3档。
竞争自行车是自行车。但他们有18个档位。
如果我给你看一辆比赛自行车并且问你"它是一辆自行车",答案是肯定的,对。但如果我问你"这辆自行车有多少齿轮",你会回答" 18",因为虽然它是自行车,但它是一个专门的这种类型的自行车没有3个齿轮作为普通自行车,但是18。
与Java对象相同:
Base bObj = new Derived();
与
相同Bike bike = new CompetitionBike();
即。你正在建造一辆自行车,而自行车的具体类型是#34;竞赛自行车"。所以,如果你问自行车有多少档,答案就是18:
bike.getGears(); // 18
同样,
bObj.bar();
将调用在对象的具体类型(Derived)中定义的bar()方法。所以"在Derived.bar()"将被打印。
静态方法不遵循这些规则,因为静态方法不是在对象上调用,而是在类上调用。
致电bObj.foo(bObj)
是合法的,但实践非常糟糕。您应该拨打的是Base.foo()
或Derived.foo()
,具体取决于您要拨打的方式。并且将调用在给定类上定义的方法。当您执行错误的事件并调用bObj.foo()
时,编译器实际上会将bObj
转换为声明的类型的bObj
,这是Base
。
答案 1 :(得分:1)
您已经发现了静态和非静态方法之间的区别。
根据调用它们的类的类型调用静态方法。例如,在您Base b = new Derived();
的情况下,b.staticMethod()
会调用Base
。这就是为什么你永远不应该从对象调用静态方法 - 这是不必要的,因为你可以调用Base.staticMethod()
但是,如果调用b.nonstaticMethod()
,将调用Derived类中的非静态方法。这就是Java管理继承的方式。
如需进一步阅读,我建议您阅读Java Tutorial on Inheritance