Java面向对象(三)继承

面向对象三大特性:封装、继承、多态。

一、继承
1.1继承的理解

生活中的继承
当你放弃学习编程,只能失败地回去继承亿万家业了,这是生活中继承,但大部分人都只能回去继承一个锄头和几块田

请添加图片描述
程序中的继承

  • 程序中的继承,是类与类之间特征和行为的一种赠与或获得。
  • 两个类之间的继承关系,必须满足“is a”的关系。请添加图片描述
    继承是满足is-a形式的,一般来说,子类拥有父类的所有特征,若不同的就重写和添加,越是继承,越是精细。
  • 功能越精细,重合点越多,越接近直接父类。
  • 功能越粗略,重合点越少,越接近Object类。(万物皆对象的概念)请添加图片描述

例如:就行如果定义一个动物类,那么我定义为 “能运动的,由细胞组成”的为动物。

那么我创建一个猫猫类,猫是肯定是动物的,所以继承了动物类,但它身上又有很多特征,如爱吃鱼,喵喵叫等

这时候我有一只波斯猫,也肯定属于猫科的,有猫猫类的所有特征,但它的毛色是白色的,眼睛是蓝色的,叫声为“喵呜”(这个不同,需要重写)

这么一来,波斯猫是继承了猫猫类的几乎所有特征,同时也继承了动物类的特征,同时还添加了很多自己的特征

所以说这是越分越细,越分越大的一个过程(由小变大过程)。

1.2继承的属性和方法

在java里,extends为继承

//动物类
public class Animal {
    boolean live = true;
    String make = "cell";

    public void move(){
        System.out.println("动物能动");
    }
}
public class Animal {
    boolean live = true;
    String make = "cell";

    public void move(){
        System.out.println("动物能动");
    }
}

//猫猫类
public class Cat extends Animal {

	增加了两个特征
    public void eat(){
        System.out.println("爱吃鱼");
    }
    public void say(){
        System.out.println("喵喵叫");
    }
}
//下面调用一下猫猫类
public class Demo01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println("活的:" + cat.live);        //动物类的
        System.out.println("组成:" + cat.make);    //动物类的
        cat.eat();
        cat.say();
        cat.move();   //动物类的
    }
}

结果:
活的:true
组成:cell
爱吃鱼
喵喵叫
动物能动

可以看到,猫猫类没有定义live 和make 属性和move 方法(动物类定义了),但猫猫类继承了动物类,也能用它的属性和方法。

1.2.1继承的属性和方法修改

有人认为,猫不是细胞做的,是水做的,这我也不好反驳,有人说后面的move内容应该改为 “猫好动”,这我觉得非常合理

public class Cat extends Animal {
    String make = "water";     //修改一
    public void eat(){
        System.out.println("爱吃鱼");
    }
    public void say(){
        System.out.println("喵喵叫");
    }

    @Override
    public void move() {      //修改二
        System.out.println("猫好动");
    }
}
//实例化一下运行
public class Demo01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println("活的:" + cat.live);      //这是修改过的
        System.out.println("组成:" + cat.make);
        cat.eat();
        cat.say();
        cat.move();      //这是修改过的
    }
}

结果:
活的:true
组成:water
爱吃鱼
喵喵叫
猫好动
1.2.2 方法的重写(重点)

当父类的方法不适合于子类时候,就进行重写

move()方法被我修改过了,在java里这叫重写,重写只发生在继承里

读者也可以看到,重写的方法上面顶着一个“@Override”,这个标志着该方法是重写过的(有的编辑器会显示这个,有的不会)

重写的原则(重点)

//重写前
public void move(){
    System.out.println("动物能动");
}

//重写后
public void move() {      //修改二
    System.out.println("猫好动");
}

重写只能改动访问修饰符和方法里面的内容

  • 不能改动参数,和返回值类型,更不能改变方法名了

  • 而改动访问类型,只能由小变大(public是最大了,不能改变,可以由private 改成public)一般比较少改动

  • 如果改变了参数,那不叫重写了,叫重载了,和重载还是很有区别的

1.3继承的构造方法

1.3.1继承无参构造
原理上,构造方法是不算继承的,继承是指类的继承(没实例化前就继承好了),构造方法是实例化之后才有的

但是,但你在父类也写上了构造方法后,就会发现,构造方法也继承过去了

(下面的我把它整理到一起,方便读者阅读)

//动物类
public class Animal {
    public Animal(){
        System.out.println("我是动物");
    }
}

//猫猫类
public class Cat extends Animal {
    public Cat(){
        System.out.println("我是猫,喵~");
    }
}

//实现猫猫类
public class Demo01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
    }
}
结果:
我是动物
我是猫,喵~

可以看到,实现猫猫类后,他会自动先调取动物类构造方法

但是,构造方法不是在实例化才会执行,是实例化的标志吗,难道实现猫猫类的同时,也把动物类也实现呢?

对的!!你可以想成这样,猫猫类把动物类继承了,相当于把动物类融合在一起了,实例化猫猫类相当于把大家一起实例化了。

1.3.2继承有参构造
这时候可能不服了,其他的我可以和父类像,但构造方法我不想相同

如果无参构造会继承的话,那我值设定有参构造,我又不传参,看你怎么办

//动物类,改为有参构造
public class Animal {
    public Animal(int age){
        System.out.println("我还是动物");
    }
}

//猫猫类
public Cat(){
    System.out.println("我是猫,喵~");       //报错了
    }
}
报错:There is no default constructor available in 'demo.Animal'
Animal类没有默认的构造方法可用

这时必须改成这样才行

public class Cat extends Animal {
    public Cat(){
        super(18);     //18是随意传入参数,super()这个是调用父类的构造方法意思
        System.out.println("我是猫,喵~");
    }
}

总结

  • 当父类只有无参构造时候,子类实例化会先调用父类的无参构造,再调用自己的构造方法
  • 当父类只有有参构造时候,子类实例化必须要先实现父类的有参构造(可以试下,不实现会报错)
  • 当父类既有无参构造,又有有参构造时,子类实例化会默认实现无参构造,若调用父类的有参构造需要自己手动进行了

也就是说,无论如何都要实现父类的构造方法,你是改变不了继承父类的血脉这个事实的。

二、this 和 super

上面涉及了super, super和this是相似的

  • this -----代表当前类
    this() -----代表调用当前类的构造方法
    this.属性-----代表当前类属性
    this.方法()-----代表当前类的方法
  • super -----代表当前类的父类
    super() -----代表调用父类的构造方法
    super.属性-----代表父类的属性
    super.方法()-----代表父类的方法

在继承关系中,为什么会自动调用父类的无参构造呢,因为继承时候,有很多你看不见的super 在你的类里面,包括父类的无参构造super()

同时,super()和this()是不能同时出现在一个构造方法(包括其他普通成员方法)里的。

注意,无论有没有写构造方法,在我们创建一个类的时候,java都会自动帮我们建立一个空白的无参构造,直到我们创建了一个构造方法它才会消失

所以说,实例化必会实现该类的构造方法!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值