一、合成
在新类里简单地创建原有类的对象。我们把这种方法叫作“合成”

为进行合成,我们只需在新类里简单地置入对象句柄即可。举个例子来说,假定需要在一个对象里容纳几个 String对象、两种基本数据类型以及属于另一个类的一个对象。对于非基本类型的对象来说,只需将句柄置于新类即可;而对于基本数据类型来说,则需在自己的类中定义它们。例:

class Demo1_4 {
    Demo4_4 d3 = new Demo4_4();
}
class Demo4_4 {
    public Demo4_4() {
        System.out.println("Demo4_4");
    }
}

 

编译器并不只是为每个句柄创建一个默认对象,因为那样会在许多情况下招致不必要的开销。如希望句柄得到初始化,可在下面这些地方进行:
(1) 在对象定义的时候。这意味着它们在构建器调用之前肯定能得到初始化。
(2) 在那个类的构建器中。
(3) 紧靠在要求实际使用那个对象之前。这样做可减少不必要的开销——假如对象并不需要创建的话。

class Demo4_4 {
    //在对象定义的时候。这意味着它们在构建器调用之前肯定能得到初始化。
    private String s=new String("wangyang");
}

class Demo2_4 {
    //在那个类的构建器中。
    private String s;
    public Demo2_4() {
        s=new String("wangyang");
    }
}

class Demo3_4 {
    //紧靠在要求实际使用那个对象之前。这样做可减少不必要的开销——假如对象并不需要创建的话。
    private String s;
    public void doTest(){
        s=new String("wangyang");
        System.out.println(s);
        
    }
}

 

 

二、继承

第二种方法则显得稍微有些技巧。它创建一个新类,将其作为现有类的一个“类型”。我们可以原样采取现有类的形式,并在其中加入新代码,同时不会对现有的类产生影响。这种魔术般的行为叫作“继承”

  1. 继承的语法
    java中,其实只要你创建了一个类,其实这个类都是继承了一个根类(object类)

    需要继承的时候,我们会说:“这个新类和那个旧类差不多。”为了在代码里表面这一观念,需要给出类名。但在类主体的起始花括号之前,需要放置一个关键字extends,在后面跟随“基础类”的名字。若采取这种做法,就可自动获得基础类的所有数据成员以及方法。

    class Cleanser {
    private String s = new String("Cleanser");
    public void append(String a) { s += a; }
    public void dilute() { append(" dilute()"); }
    public void apply() { append(" apply()"); }
    public void scrub() { append(" scrub()"); }
    public void print() { System.out.println(s); }
    public static void main(String[] args) {
    Cleanser x = new Cleanser();
    x.dilute(); x.apply(); x.scrub();
    x.print();
    }
    }
    public class Detergent extends Cleanser {
    // Change a method:
    public void scrub() {
    append(" Detergent.scrub()");
    super.scrub(); // Call base-class version
    }
    // Add methods to the interface:
    public void foam() { append(" foam()"); }
    // Test the new class:
    public static void main(String[] args) {
    Detergent x = new Detergent();
    x.dilute();
    x.apply();
    x.scrub();
    x.foam();
    x.print();
    System.out.println("Testing base class:");
    Cleanser.main(args);
    }
    } ///:~

    需要着重强调的是Cleanser 中的所有类都是public属性。请记住,倘若省略所有访问指示符,则成员默认为“友好的”。这样一来,就只允许对包成员进行访问。在这个包内,任何人都可使用那些没有访问指示符的方法。例如,Detergent 将不会遇到任何麻烦。然而,假设来自另外某个包的类准备继承Cleanser,它就只能访问那些public 成员。所以在计划继承的时候,一个比较好的规则是将所有字段都设为private,并将所有方法都设为public(protected 成员也允许衍生出来的类访问它;以后还会深入探讨这一问题)。当然,在一些特殊的场合,我们仍然必须作出一些调整,但这并不是一个好的做法。注意Cleanser 在它的接口中含有一系列方法:append(),dilute(),apply(),scrub()以及print()。由于Detergent 是从Cleanser 衍生出来的(通过 extends关键字),所以它会自动获得接口内的所有这些方法——即使我们在 Detergent 里并未看到对它们的明确定义。这样一来,就可将继承想象成“对接口的重复利用”或者“接口的再生”(以后的实施细节可以自由设置,但那并非我们强调的重点)。
    正如在scrub()里看到的那样,可以获得在基础类里定义的一个方法,并对其进行修改。在这种情况下,我们通常想在新版本里调用来自基础类的方法。但在 scrub()里,不可只是简单地发出对scrub()的调用。那样便造成了递归调用,我们不愿看到这一情况。为解决这个问题,Java 提供了一个 super 关键字,它引用当前类已从中继承的一个“超类”(Superclass)。所以表达式super.scrub()调用的是方法 scrub()的基础类版本。

    进行继承时,我们并不限于只能使用基础类的方法。亦可在衍生出来的类里加入自己的新方法。这时采取的做法与在普通类里添加其他任何方法是完全一样的:只需简单地定义它即可。extends关键字提醒我们准备将新方法加入基础类的接口里,对其进行“扩展”。foam()便是这种做法的一个产物。在Detergent.main()里,我们可看到对于Detergent 对象,可调用Cleanser 以及Detergent 内所有可用的方法(如foam())。

  2.  初始化基础类(其实就是子类实例化肯定会父类也会实例化,有父才有子---就是调用子类的构造器的时候,也会调用父类的构造器,如果父类中没有无参构造器,需要用super(**),显示调用)

    由于这儿涉及到两个类——基础类及衍生类,而不再是以前的一个,所以在想象衍生类的结果对象时,可能会产生一些迷惑。从外部看,似乎新类拥有与基础类相同的接口,而且可包含一些额外的方法和字段。但继承并非仅仅简单地复制基础类的接口了事。创建衍生类的一个对象时,它在其中包含了基础类的一个“子对象”。这个子对象就象我们根据基础类本身创建了它的一个对象。从外部看,基础类的子对象已封装到衍生类的对象里了。

    当然,基础类子对象应该正确地初始化,而且只有一种方法能保证这一点:在构建器中执行初始化,通过调用基础类构建器,后者有足够的能力和权限来执行对基础类的初始化。在衍生类的构建器中,Java 会自动插入对基础类构建器的调用。下面这个例子向大家展示了对这种三级继承的应用:

    //: Cartoon.java
    // Constructor calls during inheritance
    class Art {
    Art() {
    System.out.println("Art constructor");
    }
    }
    class Drawing extends Art {
    Drawing() {
    System.out.println("Drawing constructor");
    }
    }
    public class Cartoon extends Drawing {
    Cartoon() {
    System.out.println("Cartoon constructor");
    }
    public static void main(String[] args) {
    Cartoon x = new Cartoon();
    }
    } ///:~
    Art constructor
    Drawing constructor
    Cartoon constructo
    View Code

相关文章:

  • 2021-11-23
  • 2021-12-16
  • 2021-06-09
  • 2021-07-13
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-24
  • 2021-06-13
  • 2021-09-02
  • 2021-05-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案