版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
JAVA中继承子父类成员函数的使用
我把成员函数理解为就是类里面的功能,或者说是方法.
子父类的成员函数调用可以是这样的
例如:
class Fu{
void show1()
{
System.out.println("fu show run");
}
}
class Zi extends/*继承*/ Fu{
void show2()
{
System.out.println("zi show run");
}
}
public class ExtendsDemo{
public static void main(String[] args){
Zi z = new Zi();
z.show1();
z.show2();
}
}
这样我们new了一个叫z的对象,我们可以同时调用两个类中的方法.
在内存它是这样子的:
随着编译,类加载进入方法区,main函数进栈
由于Zi 类是Fu 类的子类,所欲 Zi类里面有一个super的指向了父类
mian函数里面创建了一个叫z的对象,于是进堆了.
这时我们调用了方法:z.show1();
这时z就通过堆内存地址找到Zi,然后先查找zi里面的方法区有没有show1();
发现没有,然后又发现Zi里有个父类,即通过super进入父类里面查找,发现有,
于是执行.
z调用另一个方法:z.show2();
这时z就通过堆内存地址找到Zi,然后先查找zi里面的方法区有show2();于是就执行了.
当子父类里面的成员函数名都是一样的时候,其实也是一样理解的时候
如:
class Fu{
void show()
{
System.out.println("fu show run");
}
}
class Zi extends/*继承*/ Fu{
void show()
{
System.out.println("zi show run");
}
}
public class ExtendsDemo{
public static void main(String[] args){
Zi z = new Zi();
z.show();
}
}
我们的输出结果是:zi show run
具体我们可以看一下图解
当调用z方法时:z通过地址找到推的对应内存,然后先找自己类里面的方法名,发现有,直接就执行了.
我们把这种叫做覆盖.
当子父类中出现成员函数一摸一样的情况,会运行子类的函数.
这种现象,称为覆盖操作,这是函数在子父类中的特性.
函数的两个特性:
1.重载. 同一个类中.overload
2.覆盖. 子类中. 覆盖也称为重写.或者叫覆写.override
覆盖注意事项:
1.子类方法覆盖父类方法时,子类权限必须大于等于父类的权限.
(当父类的方法是void时,子类的方法也是void时,它们两个的权限是相同的,可以进行覆盖操作.)
(但当父类的方法是public,子类的方法是void时,这时子类就不能对父类进行覆盖操作.)
2.静态只能覆盖静态,或被静态覆盖.
(当父类的方法是private时,子类的方法也是private时,它们两个都是静态的,可以进行覆盖操作.)
(当父类的方法不是private时,子类的方法是private时,它们可以进行覆盖操作.)
(但当父类的方法是private,子类的方法不是时,这时子类就不能对父类进行覆盖操作.)
覆盖应用
这里什么时候使用覆盖操作我们可以这样理解:
假定我们现在手机只有一个打电话的功能
这个功能我们把它封装在一个类中(这里就是简单的比喻,实际代码量肯定很多)
class Phone{
void show()
{
System.out.println("通话");
}
}
public class PhoneDemo{
public static void main(String[] args){
Phone p = new Phone();
p.show();
}
}
然后突然有一天,我们想要给这个手机增加来电大头贴和电话视频的功能,也就是升级.
这时我们肯定是不能直接通过修改那个已经封装好的类的.
因为一修改肯定不是修改一处,而是要修改很多东西,这会给升级带来灾难.
所以一般不在源代码进行规模的修改.
我们会定义新一个类,然后在这个新的类写需要的新功能,然后继承上面的版本的类.
然后把new的Phone类修改成这个新的NewPhone类就行了.
即:
class Phone{
void show()
{
System.out.println("通话");
}
}
class NewPhone{
void show()
{
super.call();
System.out.println("来电大头贴");
System.out.println("电话视频");
}
}
public class PhoneDemo{
public static void main(String[] args){
NewPhone p = new NewPhone();
p.show();
}
}
什么时候使用覆盖操作?
当对一个类进行扩展时,子类需要保留父类的功能声明,
但是要定义子类中该功能的特有内容时, 就使用覆盖操作完成.