首页 > 学院 > 开发设计 > 正文

继承

2019-11-08 01:59:07
字体:
来源:转载
供稿:网友

继承

概念

继承是面向对象编程的三大特征之一,也是实现代码复用的重要手段。java中继承具有单继承的特点,每一个类只可以直接继承一个父类,即直接父类,不可以同时继承多个类。但是继承是可以多层继承的,即:父类还有父类,顶级的父类为Object类。也就是说,任何类都是Object的子类,Object是任何类的父类。

 

如果编写的类没有直接继承其他类,默认继承的是Object类

子类 了父类的一些特征。子辈从父辈那里可以继承一笔财富称为继承,子类从父类那里可以继承一些代码称为继承。

继承是如何实现代码的复用?

以已有的类作为父类(基类),从这个父类已有的功能和属性上,在新的类(子类)中,添加其他方法和属性,达到复用代码的目的,而不用再编写父类已存在的代码,这样就达到了代码的复用!

提示:

当我们描述一类事物时候,发现这些事物具备相同的属性,我们将这些共性属性进行抽取,用单独的类来描述共同的属性,让这类事物继承抽取出来的类描述的对象,实现的代码的复用。但是请注意,继承是一类事物共性的向上抽取,所以不能单纯的为了简写代码而使用继承。

JavaJDK中提供了大量的类,这些类通过一层一层的继承,形成一个庞大的继承树,最顶级为Object类,一定要注意,这个继承树的形成是N多个类的共性的抽取,一层一层抽取共性,直至抽取到Object类,而不是说:所有功能的类都是通过Object派生出去的!

//描述猫的时候,继承狗,虽然也具备了name属性,但是意义完全错误。

class Cat extends Dog

{

    String id;

}

如果在描述对象时,只是为了简写代码,不可以使用继承的特性定义了一些和描述对象完全不相关的成员。

如果只是为了简写代码的编写,完全可以将这些不相关的代码编写一个单独的工具类来实现。

 class Dog {    Stringname;    Stringage;    voidmethod1(){        System.out.PRintln("今天星期一");    }    voidmethod2(){        System.out.println("天气晴");    }    voidmethod3(){        System.out.println("今天没雾霾");    }}  class DaoMang extends Dog{    /*在这里编写代码时候,需要用到父类的方法,可以    直接调用,编写代码确实很爽,但是这和继承思想    完全没有任何关系!因为执行父类的那些方法和描述    对象没有任何关系!!*/    voidmethod(){            method1();    }   }编写dog继承类代码。class Dog {    Stringname;    Stringage;    voidworking(){        System.out.println("看家!");    }}  class DaoMang extends Dog{    String id;}

特点:

java继承通过使用extends关键字来实现,实现继承的类被称为子类,被继承类称为父类。例如:动物是狗的父类,狗是哈士奇的父类。

定义格式:

修饰符 class 子类 extends 父类{

 

}

重写:Override:

子类继承父类后,在原有的基础上可以进行扩展,如新增属性、方法,但是有一种情况,例如:狗类具有工作方法搜救犬的工作是搜救,导盲犬的功能是导盲,那这个时候他们的工作方法内容就不一样了,我们需要将他们的工作方法进行单独的修改,那么这个修改的动作就是重写。

定义:子类继承父类后,如果子类的方法与父类的方法名称、参数个数及返回值类型完全一致时,就称为子类中的这个方法重写了父类中的方法。同理,如果子类中重复定义了父类中的已有的属性,则称此子类中的属性重写了父类中的属性。

子类重写了父类的方法或属性,那么该方法或属性便属于子类,而不属于父类,如果还想调用父类中的被重写的方法或属性,使用super.方法名/参数名的方式调用即可。

 

 

class Test{    publicstatic void main(String[] args){        DaoMangdm = new DaoMang();        dm.working();        Soujiusj = new Soujiu();        sj.working();    }}  class Dog {    Stringname;    Stringage;    void working(){        System.out.println("看家!");    }}  class DaoMang extends Dog{    String id;    voidqita(){       }    voidworking(){        System.out.println("引路!");    }}class Soujiu extends Dog{    String id;    voidworking(){        System.out.println("搜救!");    }}

spuer关键字

定义: super代表当前对象的父类对象。

当创建子类对象,最先拥有的应该是它的父类对象,那么可以使用super关键字代表父类对象,达到访问父类成员的目的!

父类对象都没有怎么可能创建子类对象?

子类覆盖了父类的方法后,子类对象无法直接调用被覆盖的父类中的方法,那么可以使用super关键字来实现调用父类的方法,或者也可以使用类名.方法名调用,但前提这个方法是静态方法(类方法)。

通过super找到该对象的父类对象:

    voidworking(){        super.working();        System.out.println("引路!");    }

通过Dao.静态方法执行代码:

     static void working(){        Dog.working();        System.out.println("引路!");    }

之前的this关键字是代表当前对象本身。这个时候super代表的是父类对象本身。

同样,super和this不能出现在static关键字修饰的方法中。

因为:static修饰的是静态的,super、this关键字描述的是对象,静态成员是优先于对象存在的。用存在的东西访问不存在的东西是错误的。

 

 

验证:子类调用到父类的属性,该属性属于父类而不属于子类。

1、 %20在父类中定义name属性,子类没有定义name属性。

2、  在测试时候,调用子类的name属性。

3确定这个子类修改了的name属性其实是属于父类的!

证明:

1、  父类对象被子类引用。

2、  子类继承父类的属性,只是引用指向了父类,并没有将父类的属性进行单独的复制一份作为子类对象本身的属性。

导盲犬与搜救犬的父类对象是同一个吗?

每次创建子类对象,都会单独创建一个该子类的父类对象!他们的父类对象不是同一个,但是他们的父类是同一个!

调用父类构造器:

class Dog {    publicDog(String message){        System.out.println(message);    }        Stringname;}  class DaoMang extends Dog{       publicDaoMang(){        super("abc");    }    String id;     static void working(){        System.out.println("引路!");    }}

创建一个子类对象,发生了什么未知的事情?

class Test{    publicstatic void main(String[] args){        /*        创建子类对象发生了:        1、先执行父类静态代码块        2、执行子类静态代码块        3、执行父类的构造代码块        4、执行父类的构造方法        5、执行子类的构造代码块        6、执行子类的构造方法    */        DaoMangdm = new DaoMang();    }}class Dog {    static{        System.out.println("Dog类的静态代码块执行了!");    }    {        System.out.println("创建Dog对象时构造代码块");    }     publicDog(){        System.out.println("Dog的构造器执行了!");    }}  class DaoMang extends Dog{    static{        System.out.println("DaoMang类的静态代码块执行了!");    }    {        System.out.println("创建DaoMang对象时构造代码块");    }    publicDaoMang(){        System.out.println(id  + "DaoMang的构造器执行了!");    }} 

 

设置父类与子类同名的成员属性

 

class Test{    publicstatic void main(String[] args){        DaoMangdm = new DaoMang();        dm.setName("金毛");        dm.setSuperName("SuperName");        Stringname = dm.getName();        StringsuperName = dm.getSuperName();        System.out.println("子类对象的name:" + name +"/n 父类对象的name是:" + superName);    }}class Dog {    Stringname;}  class DaoMang extends Dog{    Stringname;    publicvoid setName(String name){        this.name= name;    }    publicvoid setSuperName(String name){        super.name= name;    }    publicString getName(){        returnname;    }    publicString getSuperName(){        returnsuper.name;    }}

 

 

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表