组合和继承—-复用类的两种方法

  • A+
所属分类:JAVA


共计 2113 个字符,预计需要花费 6 分钟才能阅读完成。

日常开发过程中,我们程序猿更多时候会自嘲CV工具人,这是因为在业务逻辑开发时,重复代码太多了,如果真的要去全盘Copy的话,会显得很Low,这样我们就会想到复用代码,既省时又简洁。
那我们这里就会提及复用类的两种方法:①组合、②继承

语法

将对象引用置于新类成员变量位置;

/**
 * @author plm
 * @create 2021/3/4 23:01
 */
class Pen {
    private String s;

    public Pen() {
        System.out.println("Pen Construct.");
        s = "Construct";        // 在类的构造器中
    }

    @Override
    public String toString() {
        return "Pen{" +
                "s='" + s + '\'' +
                '}';
    }
}

public class Desk {
    private String
            s1 = "World",       // 在定义对象的地方
            s2 = "Peace",
            s3,
            s4;
    private Pen pen;
    private int i;
    private float f;

    public Desk() {
        System.out.println("Desk Construct.");
        s3 = "Hello";
        f = 2.43F;
        pen = new Pen();
    }

    {
        i = 45;                 // 使用实例初始化
    }

    @Override
    public String toString() {
        if (s4 == null) {
            s4 = "Hi";         // 惰性初始化(懒加载)
        }

        return "Desk{" +
                "s1='" + s1 + '\'' +
                ", s2='" + s2 + '\'' +
                ", s3='" + s3 + '\'' +
                ", s4='" + s4 + '\'' +
                ", pen=" + pen +
                ", i=" + i +
                ", f=" + f +
                '}';
    }

    public static void main(String[] args) {
        Desk desk = new Desk();
        System.out.println(desk.toString());
    }
}

/* 输出
Desk Construct.
Pen Construct.
Desk{s1='World', s2='Peace', s3='Hello', s4='Hi', pen=Pen{s='Construct'}, i=45, f=2.43}
 */

初始化时机

如上代码,有以下几处位置:
在定义对象的地方;(总是可以在构造方法被调用之前初始化)
在类的构造方法中
在使用到对象之前才会初始化,称为惰性初始化;(不必每次new对象就初始化,可以减少额外的开销)
使用实例初始化

语法

关键字extends,从现有类获得继承信息(所有的域和方法)构建出新类;

/**
 * @author plm
 * @create 2021/3/4 23:40
 */
class Dword {
    public Dword() {
        System.out.println("Dword Construct.");
    }

    void dp() {
        System.out.println("dp.");
    }
}

class Nword extends Dword {
    public Nword(int i) {
        System.out.println("Nword Construct.");
    }

    void dp_1() {
        System.out.println("dp_1.");
    }
}

public class Sword extends Nword {
    private int i = 7;

    public Sword(int i) {
        super(i);
        System.out.println("Sword Construct.");
    }

    void dp_2() {
        super.dp();
        super.dp_1();
        System.out.println("dp_2.");
    }

    public static void main(String[] args) {
        Sword sword = new Sword(6);
        sword.dp();
        sword.dp_1();
        sword.dp_2();
    }
}

/* 输出
Dword Construct.
Nword Construct.
Sword Construct.
dp.
dp_1.
dp.
dp_1.
dp_2.
*/

tips:supper关键字表示超类,想要调用基类的方法可使用supper.基类方法名()即可;

初始化基类

导出类进行初始化时,会先调用supper调用基类的构造方法进行初始化(此为隐式地调用基类的无参构造);
基类在导出类访问它之前就已经完成了初始化;

带参的构造方法

必须使用关键supper 显示地调用基类构造方法(如上代码),否则编译器就会提醒你:

There is no default constructor available in ‘cn.peiluming.test2.test1.Nword’

方法重写

既然子类拥有了父类的所有方法,那如果需要对父类方法进行自定义实现,这里就会涉及到重写,也是后面多态的前提之一
JDK 1.5 之后引入注解@Override,对你的重写方法进行校验;

组合一般多用于Has-a,在新的类中使用现有类的属性,而并非它的方法;多加上private修饰符!
继承多用于Is-a,常常结合向上转型使用,因为继承可以确保基类中的方法,在导出类中同样生效;

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: