继承在面向对象中的提现

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("显示头像");
    }
}

 总结以上,当一个类是另外一个类的一种时,可以通过继承,来扩展功能。如果父类具备的功能需要子类特殊定义的时候,需要重写。

在复写的过程中,有需要注意一下:

  • 子类方法覆盖父类方法,必须需要保证子类方法权限大于父类的方法权限。
  • 需要注意的是,在子父中,静态方法只能覆盖静态方法,或者被静态覆盖

 

posted @ 2013-12-01 22:35  lee笔记  阅读(317)  评论(0)    收藏  举报