继承

继承

概念

继承是面向对象编程的三大特征之一,也是实现代码复用的重要手段。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、  在父类中定义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;
    }
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值