C++ 和Java中的继承
在C++和Java中,继承的目的是相同的。在这两种语言中,继承用于重用代码和/或创建‘是-一个’的关系。以下示例将展示Java和C++在继承支持方面的不同。
1)在Java中,所有的类都直接或间接继承自Object类。因此,在Java中,总是存在一个类的继承树,根节点是Object Class。当你在Java中创建一个类时,它会自动继承Object Class。然而,在C++中,存在着一个类的森林;当我们创建一个不继承其他类的类时,我们就是在这个森林中创建了一棵新树。
Test类默认继承了Object类,如Java示例所示。
class Test {
// members of test
}
class Main {
public static void main(String[] args)
{
Test t = new Test();
System.out.println("t is instanceof Object: "
+ (t instanceof Object));
}
}
输出
t is instanceof Object: true
2) 在Java中,无法直接访问父类成员。(有关更多信息,请参阅此文章。)
3) 在Java中,protected成员访问修饰符的含义略有不同。即使B不继承A,在Java中,类A的protected成员也可以在其他同一包中的类B中访问(它们必须位于同一包中)。
示例,在下面的程序中,A的protected成员可以在B中访问。
class A {
protected int x = 10, y = 20;
}
class B {
public static void main(String args[])
{
A a = new A();
System.out.println(a.x + " " + a.y);
}
}
输出
10 20
4)对于继承,Java 使用 ‘extends’ 关键字。与 C++ 不同,Java 缺乏 public、protected 和 private 等继承标识符。因此,在 Java 中,我们不能改变基类成员的保护级别;如果一个数据成员在基类中是 public 或者 protected,那么在派生类中它仍然是 public 或者 protected。基类的私有成员在派生类中是不可访问的,与 C++ 中一样。
与 C++ 不同的是,在 Java 中我们不必记住继承规则,这些规则由基类访问标识符和继承标识符组成。
5)在 Java 中,虚方法是默认的。在 C++ 中我们需要显式使用 virtual 关键字(详情请参考这篇文章)。
6)对于接口,Java 使用 interface 关键字,而对于抽象类和抽象函数,则使用 abstract 关键字。
以下是一个 Java 抽象类的例子:
// An abstract class example
abstract class myAbstractClass {
// An abstract method
abstract void myAbstractFun();
// A normal method
void fun() { System.out.println("Inside My fun"); }
}
public class myClass extends myAbstractClass {
public void myAbstractFun()
{
System.out.println("Inside My fun");
}
}
下面是一个Java接口的示例。
// An interface example
public interface myInterface {
// myAbstractFun() is public
// and abstract, even if we
// don't use these keywords
void myAbstractFun();
// is same as public abstract void myAbstractFun()
}
// Note the implements keyword also.
public class myClass implements myInterface {
public void myAbstractFun()
{
System.out.println("Inside My fun");
}
}
7)与C++不同,Java不支持多继承。一个类不能从多个其他类派生。另一方面,一个类可以实现多个接口。
8)在C++中,默认函数Object() { [native code] }会自动调用父类的函数,但如果我们想调用父类的带参数函数Object() { [native code] },我们必须使用初始化列表。在Java中,父类的默认函数Object() { [native code] }会自动调用,就像在C++中一样,但如果我们想调用带参数函数Object() { [native code] },我们必须使用super来调用父类的函数Object() { [native code] }。请看下面的Java示例。
package main;
class Base {
private int b;
Base(int x)
{
b = x;
System.out.println("Base constructor called");
}
}
class Derived extends Base {
private int d;
Derived(int x, int y)
{
// Calling parent class parameterized constructor
// Call to parent constructor must be the first line
// in a Derived class
super(x);
d = y;
System.out.println("Derived constructor called");
}
}
class Main {
public static void main(String[] args)
{
Derived obj = new Derived(1, 2);
}
}
输出
Base constructor called
Derived constructor called