继承在面向对象中的提现
1. 继承的引入
我们都知道,在java中,可以通过一个类来描述某一类事物固有的属性和行为,在当前类中,基础之上我们还可以构造我们想要的函数,在已经新建好的类的基础之上,可以new一个对象,来调用相应的功能。说起来很抽象,我们来举个例子。我们用代码描述多类事物,学生Student和工人Worker,学生都工人都有属性年龄,姓名。但是学生有学生的行为就是学习,工人有工人的行为work。代码体现如下:
/* 创建一个学生类 */ class Student { String name; int age; ////学生有学习的行为 void study() { System.out.println("study"); } } /* 创建一个工人类 */ class Worker { String name; int age; //////工人有工作的行为 void work() { System.out.println("work"); } }
通过代码的演示,我们可以发现学生和工人有共同的属性age和name,是不是代码的复用性很差呢?我们是否可以把共同的属性抽取出来呢,放在一个单独的class中呢?然后学生和工人共同使用呢?学生和工人都属于人类person,我们试想一下,可以单独创建一个类Person,具有属性age和name,然后学生类和工人类共同使用Person类中的age和name的属性。但是怎么样才能让Person这个class和Student,Woker这个类扯上关系呢?为了让类与类之间有关系,Java中提供继承这种机制。需要用到关键字extends。代码体现如下:
//将学生和工人的共性抽取到Person这个类中 class Person { String name; int age; } //学生通过extends继承Person,即Person为Student的父类 class Student extends Person{ //学生类中的自己特有的学习行为 public void study(){ System.out.println(name+":同学正在学习。。。。"); } } //工人通过extends继承Person,即Person为工人的父类 class Worker extends Person{ //工人类中的自己特有的工作行为 public void work(){ System.out.println(name+":工人正在工作。。。。"); } } //测试类 public class Test{ public static void main(String[] args) { Student s = new Student(); s.name = "小明"; s.study(); Worker w = new Worker(); w.name = "王五"; w.work(); } }
使用继承,明显提高了代码的复用性。
2. 继承的使用
继承让类与类之间产生了关系,那么在我们的开发过程中,什么时候使用继承呢?要使用继承,必须保证类与类之间有所属的关系,即子类是父类的一种,比如香蕉是水中中的一种,狼是犬科中的一种。需要我们注意的是,在Java中只支持单继承,不支持多继承,即一个类只有有一个父类,不能有多个父类。但是Java中支持多层继承,即class A可以继承class B,class B 也可以继承class C。另外一个问题我们又遇到就是,如果父类中有成员变量有与子类中成员变量相同的,那么该怎么办呢?我们如何调用父类中的成员变量呢?
当在子父类中出现了同名成员变量,在子类中若要访问父类中的成员变量,必须使用super关键字来完成。代码体现如下:
class Fu { //Fu中的成员变量。 int num = 5; } class Zi extends Fu { //Zi中的成员变量 int num = 6; void show() { //访问父类中的num System.out.println("Fu num="+super.num); //访问子类中的num2 System.out.println("Zi num="+this num); } } class Demo { public static void main(String[] args) { Zi z = new Zi(); //创建子类对象 z.show(); //调用子类中的show方法 } }
this关键字代表本类的对象引用。super代表父类的内存空间,不是父类的引用。需要注意的是,以上的代码中,父类中的成员变量是没有权限关键字修饰的,如果用private修饰,子类是无法调用父类中的成员变量的,父类中的方法亦如此。当程序调用方法的时候,会现在子类中查找有没有对应的方法,如果子类存在就会执行子类中的方法,若子类中不存在就执行父类中相应的方法。代码体现如下:
class Fu{ public void show(){ System.out.println("Fu类中的show方法执行"); } } class Zi extends Fu{ public void show2( ){ System.out.println("Zi类中的show2方法执行"); } } public class Test{ public static void main(String[] args) { Zi z = new Zi(); z.show(); //子类中没有show方法,但是可以找到父类方法去执行 z.show2(); } }
在上面的代码中,子类中的方法show2与父类中的方法show是不同的,当子类中的方法也为show呢?出现于父类一模一样的方法的时候呢?在Java中,子父类中出现相同的方法(函数的返回值,函数名,参数列表一样)时,就会出现override的操作,即就是重写,复写或者覆盖。这样既沿袭了父类的功能,又定义了子类特有的内容。我们举个例子:我们来描述一个手机,手机具有发短信,打电话,和来电显示的功能,后来新的一代手机,添加了显示了姓名和头像。在原有描述手机的类的基础之上,我们可以定义一个新的手机类,并且在新的类中覆盖来电显示,在其中添加显示姓名和头像的功能。代码体现如下:
public class Test { public static void main(String[] args) { new NewPhone().showNum(); } } class Phone{ public void sendMessage(){ System.out.println("发短信"); } public void call(){ System.out.println("打电话"); } public void showNum(){ System.out.println("来电显示号码"); } } class NewPhone extends Phone{ //覆盖父类的来电显示号码功能,并增加自己的显示姓名和图片功能 public void showNum(){ //调用父类已经存在的功能使用super super.showNum(); //增加自己特有显示姓名和图片功能 System.out.println("显示来电姓名"); System.out.println("显示头像"); } }
总结以上,当一个类是另外一个类的一种时,可以通过继承,来扩展功能。如果父类具备的功能需要子类特殊定义的时候,需要重写。
在复写的过程中,有需要注意一下:
- 子类方法覆盖父类方法,必须需要保证子类方法权限大于父类的方法权限。
- 需要注意的是,在子父中,静态方法只能覆盖静态方法,或者被静态覆盖
浙公网安备 33010602011771号