ok()方法在继承时候发生覆盖(重写)了吗?
发生了。在子类B中的ok()方法拥有父类方法相同的方法名和参数列表(signature),所以在这里发生了重写。调用B类对象的ok()方法会print "b",父类方法被覆盖。
如果是重写了,那定义一个b类的对象还能再调用a类继承的ok()函数吗?
可以。方法就是利用super关键字。@陆萌萌 的答案已经解释了。
a类的ok()函数是在子类中隐藏了吗?能告诉我覆盖和隐藏分别应该怎么用怎么写吗?
错误。我回答这个问题主要就是为了说明这个易混点。
在Java中并没有隐藏的概念,只有重载overload和重写override,隐藏(redifine)是C++中的概念,网络上很多人将之带到了Java,以为在Java中也有这样的区分。
1.) 在C++中,同一类内相同函数名不同参数列表的函数为重载;
2.) 父类与子类间相同名字相同参数列表,且父类函数有virtual标识符的为重写;
3.) 父类与子类间相同名字不同参数列表,此时无论有无virtual标识符,或者父类与子类间相同名字相同参数列表,但是父类函数中没有virtual标识符,则为隐藏,或者说重定义redifine。
Java中,情况简化了许多。Java里没有virtual标识符,按照上面三种情况划分:
1.) 同一类内相同方法名不同参数列表的方法为重载;
2.) 父类与子类间相同名字相同参数列表,为重写(覆盖),这里与C++的区别是,Java中不需要有virtual标识符;
3.) 父类与子类间相同名字不同参数列表,此时按C++中的逻辑应该算是重定义(隐藏), 但是Java中没有隐藏的概念。在具体实现中,父类中的函数,会被继承下来,和子类中的同名函数,一起成为子类中的重载函数 。这个实现其实是与重载的定义相悖的,因为重载要求必须是在同一类内的相同名字不同参数列表的方法,而在这里,重载跨越了父类与子类。
以下为实际测试代码:
class a{
public void ok()
{system.out.println("a");}
}
class b extends a{
public void ok(int c)
{system.out.println("b");}
}
class hello{
public static void main()
{
a A =new b();
A.ok();
A.ok(1);
}
}
在Java中,这里程序会输出"a b"。子类对象中隐式地包含了ok(),ok(int c)两个重载方法。
在C++中,同样结构的代码,这里会出现编译错误,因为父类中的ok()被子类的ok(int c)隐藏,在子类对象中根本找不到ok()这个函数。
相比较而言,C++规范更明确,每种情况条分缕析;Java在实现上虽然更简单方便,但其实与重载的定义是相悖的。