前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【测开技能】Java系列(二十 六)继承(二)

【测开技能】Java系列(二十 六)继承(二)

作者头像
雷子
发布2022-09-29 20:23:13
1930
发布2022-09-29 20:23:13
举报
文章被收录于专栏:雷子说测试开发

前一篇:

【测开技能】Java系列(二十 五)继承

这一篇还是来分享继承。

super

super关键字表示父类(超类)。子类引用父类的字段时,可以用super.fieldName

如何使用呢

代码语言:javascript
复制
   class Mantou extends Food{
        @Override
        public String toString() {
            return birthcity+super.birthcity;
        }
    }

实际上,这里使用super.name,或者this.name,或者name,效果都是一样的。编译器会自动定位到父类的name字段。

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Mantou hello = new Mantou();
        hello.setBirthcity("beijing");
        System.out.println(hello.toString());
    }
}

打印下,输出结果是

但是,在某些时候,就必须使用super,例如

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Mantou hello = new Mantou("beijing",10,10);
    }
}
    class Mantou extends Food{
        protected  int score;
        public  Mantou(String bir,float price,int score){
            this.score=score;
        }
    }

但是我们在写完代码,编辑器就给报错了

结果

但是应该怎么做呢

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Mantou hello = new Mantou("beijing",10,10);
        System.out.println(hello.getBirthcity());
    }
}
    class Mantou extends Food{
        protected  int score;
        public  Mantou(String bir,float price,int score){
            super(bir,price);
            this.score=score;
        }
    }

因为在Java中,任何class的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super();,所以,Mantou类的构造方法实际上是这样。

父类的构造方法中需要参数,上面的父类就需要构造参数。就需要在super中传递参数。

父类的代码如下:

代码语言:javascript
复制
    class Food {
        protected String birthcity;
        protected float price;

        public Food(String birthcity, float price) {
            this.birthcity = birthcity;
            this.price = price;
        }

        public String getBirthcity() {
            return birthcity;
        }

        public void setBirthcity(String birthcity) {
            this.birthcity = birthcity;
        }

        public float getPrice() {
            return price;
        }

        public void setPrice(float price) {
            this.price = price;
        }
    }

假如在super中不传递参数

执行也会报错

这个告诉我们,必须要传递对应的参数,调用父类的构造方法

代码语言:javascript
复制
class Mantou extends Food{
    protected  int score;
    public  Mantou(String bir,float price,int score){
        super(bir,price);
        this.score=score;
    }
}

从上面的执行中,可以看到:

父类没有默认的构造方法,子类就必须super()并给出参数以便让编译器定位到父类的一个合适的构造方法。

子类不会继承任何父类的构造方法。子类默认的构造方法是编译器自动生成的,不是继承的。

向上转型

如果一个引用变量的类型是

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Mantou hello = new Mantou();
        System.out.println(hello.getClass());

    }
}

结果输出就是一个

如果 变量指向的是Food

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {

        Food food = new Food();
        System.out.println(food.getClass());
    }
}

结果是

现在问题来了:如果Mantou是从Food继承下来的,那么,一个引用类型为Food的变量,能否指向Mantou类型的实例?

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {

        Food food = new Mantou();
        System.out.println(food.getClass());
    }
}

结果

测试一下就可以发现,这种指向是允许的!

这是因为Mantou继承自Food,因此,它拥有Food的全部功能。Food类型的变量,如果指向Mantou类型的实例,对它进行操作,是没有问题的!

这种把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)。

向上转型实际上是把一个子类型安全地变为更加抽象的父类型:

代码语言:javascript
复制
Mantou s = new Mantou();
Food p = s; // up, ok
Object o1 = p; // up, ok

向下转型

和向上转型相反,如果把一个父类类型强制转型为子类类型,就是向下转型(downcasting)

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Food food = new Mantou();
        Mantou mantou= (Mantou) food;
        System.out.println(mantou.getClass());
    }
}

结果

但是 也会有失败的时候。

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Food food = new Food();
        Mantou mantou= (Mantou) food;

        System.out.println(mantou.getClass());
    }
}

执行下

这样是不可以的。那么如何避免呢

为了避免向下转型出错,Java提供了instanceof操作符,可以先判断一个实例究竟是不是某种类型:

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Food food = new Food();
        if (food instanceof Mantou){
            Mantou mantou= (Mantou) food;
            System.out.println(mantou.getClass());
        }
    }
}

结果

编译通过

instanceof实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false。

所以可以利用上面写的if判断,正确后再向下转型。

知识点就分享完毕了。简单实现一个继承。在Mantou类在实现一个Tianmantou,让它增加一个字段 islike

代码语言:javascript
复制
 class  Tianmantou extends Mantou{
            protected  boolean islike;

        public boolean isIslike() {
            return islike;
        }

        public void setIslike(boolean islike) {
            this.islike = islike;
        }
    }

其实很简单,继承在后续的面向对象的编程中会大量的使用。一些概念大家要牢记。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雷子说测试开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • super
  • 向上转型
  • 向下转型
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档