上一篇文章写了一个C++的类继承问题,今天遇到了一个类似的java的问题,所以就比较了一下两者在继承方面的属性和方法的情况。
一、C++中的继承
class A {
public:
int a = 0;
void foo() { printf("a_foo\n"); }
virtual void bar() { printf("a_bar\n"); }
A() { printf("A构造函数\n"); }
};
class B : public A{
public:
int a = 1;
void foo() { printf("b_foo\n"); }
void bar() { printf("b_bar\n"); }
B(){ printf("B构造函数\n"); }
};
int main()
{
A *p = new B();
cout<<p->a<<endl;
p->foo();
p->bar();
cout << endl;
B *q = new B();
cout << q->a << endl;
q->foo();
q->bar();
system("pause");
return 0;
}
输出的情况?
从结果可以得出B继承了A,里面B{a,a,foo(),foo(),bar()};
1、B中同时拥有和自己相同的属性名的父类的属性,并且系统会检索声明类中的属性;
2、C++中的继承中同名普通方法不会被重写,并且会调用声明类的方法
之前我也有点纳闷,原来指针p的情况是这样的:
(1)当调用一个对象的函数时,系统会直接去检查这个对象声明定义的类,即声明类,看所调用的函数是否为虚函数;
(2)如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。
(3)在这个实例类里,他会检查这个实例类的定义中是否重新实现了该虚函数(通过override关键字),如果是,则执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重写了该虚函数的父类为止,然后执行该父类里重写后的函数。
这是我后来在一篇文章中看到的,作者写的很好。点击打开链接
二、java中的继承
public class Main {
class Super {
public int filed = 0;
public int getFiled(){
return filed;
}
}
class Sup extends Super{
public int filed = 1;
public int getFiled(){
return filed;
}
public int getSuperFiled(){
return super.getFiled();
}
}
public static void main(String[] args) {
Super sup = new Sup();
System.out.print(sup.filed);
System.out.print(sup.getFiled());
Sup s = new Sup();
System.out.print(s.filed);
System.out.print(s.getFiled());
System.out.print(s.getSuperFiled());
}
}
运行结果:
java中,类的成员域和C++的效果一样,声明类中同名属性,但是对于方法,java中的继承,父类的同名方法会被子类的同名方法所重写,即子类{filed,filed,getFiled()},只有一个同名方法,如果是父类的引用指向子类的对象,那么引用的调用不是调用声明类的方法,而是调用了被重写之后的方法,如果希望方法不被重写,则在父类的方法加上final的修饰词。
这是一篇写的挺清晰的一个例子点击打开链接