我有这两个类:
public class A {}
public class B extends A {}
在主课程中,我会声明:
A a = new B();
B b = new B();
a和b有什么区别?这是我们在java中所谓的子类型吗?
答案 0 :(得分:5)
a
和b
之间的区别在于a
只能使用A
类提供的公共API,即使它真的是B
} type object,但使用b
,您可以同时使用A
的公共API以及B
的公共API。
例如:
假设A和B的定义如下:
// A.java
public class A
{
public void x()
{
z("X");
}
public void y()
{
z("Y");
}
protected void z(String message)
{
System.out.println(message);
}
}
// B.java
public class B extends A
{
public void a()
{
z("A");
}
public void b()
{
z("B");
}
}
这是一个演示:
// Demo.java
public class Demo
{
public static void main(String[] args)
{
A a = new B();
B b = new B();
// Can only call A's public methods
a.x();
a.y();
// a.a(); Can't use
// a.b(); Can't use
// Can call all public methods
b.a();
b.b();
b.x();
b.y();
}
}
答案 1 :(得分:1)
是的,之间存在差异。方法的可访问性因您使用的引用类型而异。
答案 2 :(得分:1)
A a = new B(); B b =新B();
a是A类的引用,b是B类的引用。超类总是可以用来指定子类对象。
引用a只能访问超类方法和属性
引用b能够访问超类及其自己的方法和属性
一个重要的事情是,功能和属性的可访问性将在运行时决定。
答案 3 :(得分:1)
以下两种情况
A a = new B();
a是B和A类的实例化。
而在
B a = new B();
a是B和B类型的实例化。
这里要注意的重要一点是(在第一种情况下)如果调用a.someMethod(),将调用B的方法,而不是A的方法(这称为动态绑定,而不是静态捆绑)。
答案 4 :(得分:0)
这是基本的继承。在B b = ...的情况下,您可以访问A和B提供的所有方法和变量,但在A情况下,您只能使用A案例中的方法和变量。
B在创建时被转换为A,但编译器不需要该信息。
public class A {
int x;
}
public class B extends A {
int y;
}
A a = new B();
B b = new B();
int c = a.x; //works
int c = a.y; //doesn't work
int c = b.y; //works
int c = b.x; //works
请记住,您始终可以在继承链中“向下”转换对象。但是你不应该向上转换一个对象,因为子类的变量可能会被使用,即使它们不存在,例如B b = new A();所以b.y很危险,因为B对象没有定义y变量。