java 面向对象三大特性之一:继承

      前言:

   继承,既是对现有类的复用。如果子类继承了父类,那么子类就拥有了父类的能力了。除此之外,子类还能加入自己新加入的方法,功能,或是重新定义从父类继承的某项功能。这样,就可以在现有的功能上开发新的功能,这样能大大减少开发的周期.

|继承的优点|

 现在我们来构建一个Cat的类

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 13:202018/3/12
 */

/**
 * 猫类
 */
public class Cat {
    private int age;//年龄
    private int weigth;//体重
    private String name;//名字

    public int getAge() {
        return age;
    }
    public Cat(int age,int weigth,String name){
        this.age=age;
        this.weigth=weigth;
        this.name=name;

    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getWeigth() {
        return weigth;
    }

    public void setWeigth(int weigth) {
        this.weigth = weigth;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void printMessage(){
        System.out.println("name:"+getName()+" weigth:"+getWeigth()+"kg  age:"+getAge());
    }
    public  Cat(){}

}

这个Cat类包含体重 名字 身高等信息,但现在我想要在这个Cat的基础上创建一个EgyptianCat的类,我要重新把之前的代码重新再写一次然后再添加新的东西下去吗?很显然这会十分的麻烦且无用,所以这时候extend 这个关键字发挥了他的用处了

public class EgyptianCat extends Cat {
    private  String color;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public EgyptianCat(int height,int weigth,String name,String color){
        super(height,weigth,name);
        this.color=color;
    }

    @Override
    public void printMessage() {

        System.out.println("name:"+getName()+" weigth:"+getWeigth()+"kg  age:"+getAge()+"color:"+getColor());
    }
}

和Cat相比,EgyptianCat就多了个一个私用属性color,通过extend继承,我们的类构建可以简洁很多,并且可以在继承的基础上重新构建一个属于我们新类的方法,这种方法叫做重写方法(PS:重写方法会调用上一层继承的被重写方法)

这里我们重写了父类的printMessage()方法,在打印信息中新加入了color属性

现在我们来new下父类和子类并且调用他们的printMessage方法查看下结果

 public static void main(String[] args) {
        Cat cat = new Cat(2,10,"jay");
        cat.printMessage();
        EgyptianCat egyptianCat = new EgyptianCat(3,5,"lois","black");
        egyptianCat.printMessage();

    }

输出结果为:

name:jay weigth:10kg  age:2
name:lois weigth:5kg  age:3 color:black

|成员的继承|

如果子类继承了父类,则:

1.子类继承父类的所有public与protect成员,无论子类是否与父类在同一个包中;

2.如果子类与父类在同一个包中,那么子类也会继承父类包访问权限

3.子类不能继承父类的私有成员,但是子类可以通过父类的public或protect方法间接访问父类的私有成员

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 22:212018/3/13
 */
public class SuperClass {
    public int public_value;
    protected  int protect_value;
    private int private_value;
    public SuperClass(){
        public_value=1;
        protect_value=2;
    }

    public int getPrivate_value() {
        return private_value;
    }

    public void setPrivate_value(int private_value) {
        this.private_value = private_value;
    }
}

在SuperClass这个类中我们声明三种访问权限的变量,让我们看下他的子类是怎么继承成员变量的

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 22:242018/3/13
 */
public class ExtendClass extends SuperClass {


    public void printMessage() {
        System.out.println("public value:"+public_value);
        System.out.println("protect value"+protect_value);
        // System.out.println("private value"+private_value); 并不能直接访问私有属性
        System.out.println("private value:"+getPrivate_value());
    }

    public static void main(String[] args) {
        ExtendClass extendClass = new ExtendClass();
        extendClass.setPrivate_value(3);
        extendClass.printMessage();

    }
}

我们新创建了一个ExtendClass类,其中声明了一个printMessage打印出成员变量的信息,让我们看下结果吧

public value:1
protect value2
private value:3

结果说明,子类能直接继承父类的public和protect成员变量,但并不能直接继承私有变量,但能通过setter和getter方法来访问private变量

|继承的向上转型和向下转型|

如果子类继承了父类,那么我们可以认为子类是父类的其中一种,是父类的特殊拓展版,例如Cat类继承于Animal类,那么我们可以把Cat看做为Animal,Cat具有Animal的所有特征,但并不能把Animal看做为Cat,因为并不是所有的Animal都是Cat.

 在Java中,我们可以把父类的引用赋值给子类的对象,然后通过父类的引用来进行操作,这种操作被称为向上转型,但是,子类的新增方法并不能进行使用和操作。我们不能把子类的引用赋值给父类的对象,就像前面所说的,可以把Cat看做为Animal,Cat具有Animal的所有特征,但并不能把Animal看做为Cat,因为并不是所有的Animal都是Cat.

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 22:432018/3/13
 */
public class Animal {
    public void walk(){
        System.out.println("Animal walk!!");
    }
    public void sleep(){
        System.out.println("Animal sleep!!");
    }
    public void eat(){
        System.out.println("Animal eat!!");
    }
}

我们现在创建一个Animal类,然后我们再创建一个Cat类继承于Animal类

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 13:202018/3/12
 */

/**
 * 猫类
 */
public class Cat extends Animal {
    private int age;//年龄
    private int weigth;//体重
    private String name;//名字

    public int getAge() {
        return age;
    }
    public Cat(int age,int weigth,String name){
        this.age=age;
        this.weigth=weigth;
        this.name=name;

    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getWeigth() {
        return weigth;
    }

    public void setWeigth(int weigth) {
        this.weigth = weigth;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void printMessage(){
        System.out.println("name:"+getName()+" weigth:"+getWeigth()+"kg  age:"+getAge());
    }
    public  Cat(){}
     public void  Meow(){
         System.out.println("meow!!!!");
     }
}

其中Cat类中新增了一个Meow的猫叫方法

现在我们来测试一下:

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 22:492018/3/13
 */
public class Test {
    public static void main(String[] args) {
        Animal cat = new Cat();
        cat.eat();
        cat.sleep();
        cat.walk();
        //但是不能调用Meow这个方法,现在我们把cat引用转为Cat
        cat=(Cat) cat;
        ((Cat) cat).Meow();
        //Cat animal = new Animal(); 编译器报错,并不能向下转型!

    }
}

结果:

Animal eat!!
Animal sleep!!
Animal walk!!
meow!!!!

正如之前所说的一样,父类引用指向子类对象不能使用子类自己新增的方法,而且如果向下转型的话编译器会报错,那么向下转型有什么作用呢?之后我们会提到.

|多态的实现|

 现在我们要编写一个动物园类,检查传入的动物是什么动物

package Test.practice.thinking_in_java.extend_test;

/**
 * @Author 7aY
 * @Description: TODO()
 * @Date :Create in 0:212018/3/15
 */
public class Zoo {
    //动物园检查动物
    public void check(Animal animal){
        System.out.println("this is animal!");

    }
    public void check(Cat cat){
        System.out.println("this is cat!");

    }
    public void check(EgyptianCat egyptianCat){
        System.out.println("this is egyptianCat!");

    }

    public static void main(String[] args) {
        Zoo zoo = new Zoo();
        Animal animal = new Animal();
        Cat cat = new Cat();
        EgyptianCat egyptianCat = new EgyptianCat();
        zoo.check(animal);
        zoo.check(cat);
        zoo.check(egyptianCat);
    }
}

结果:

this is animal!
this is cat!
this is egyptianCat!

以上的代码是check方法的重载,看上去没有任何问题.但只要我们稍加修改,用到上面的向上转型,结果则会出人意料

  public static void main(String[] args) {
        Zoo zoo = new Zoo();
        Animal animal = new Animal();
        Cat cat = new Cat();
        Animal egyptianCat = new EgyptianCat();
        zoo.check(animal);
        zoo.check(cat);
        zoo.check(egyptianCat);
    }
}

输出结果:

this is animal!
this is cat!
this is animal!

这是因为方法重载是静态的,传入参数类型是看类型的引用,前面cat的引用类型是Animal,所有编译器自动把cat传到Animal的重载方法中。

现在我们稍加修改

public class Zoo {
    //动物园检查动物

    public void check(Animal animal){
        animal.printInfo();
    }

    public static void main(String[] args) {
        Zoo zoo = new Zoo();
        Animal animal = new Animal();
        Cat cat = new Cat();
        Animal egyptianCat = new EgyptianCat();
        zoo.check(animal);
        zoo.check(cat);
        zoo.check(egyptianCat);
    }
}

结果为:

this is Animal
this is cat
this is EgyptianCat

这里说明一下,Animal 、Cat、EgyptianCat类中都有一个printInfo方法打印出自身的信息

从结果可以看出,虽然是向上转型,但是仍能准确输出类的信息,并且在Zoo类中并不需要重载方法,试想一下每当有一个新的类出现就重载一次,那么这个Zoo类的重载方法是不是太多了,以后管理起来也不方便,但使用多态的话,这需要在子类中重写方法即可,十分的方便。

【总结】

 使用继承这个关键字extend 能减少我们代码编写的工作量,但在重写的时候要注意,例如重写,类的变量继承等

因为有了继承,使得代码的复用有了千变万化的机会















 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值