Java程式設計思想第四版第七章練習
練習1:建立一個簡單的類。第二個類中,將一個引用定義為第一個類的物件。運用惰性初始化來例項化 這個物件
public class Exercise7_1 {
public static void main(String[] args) {
Second second = new Second("Init String");
second.chenked();
System.out.println(second.getSimple());
second.chenked();
System.out.println(second);
second.setSimple("New String" );
System.out.println(second);
}
}
class Simple{
String s;
public Simple(String si) {
s = si;
}
public String toString() {
return s;
}
public void setString(String sNew) {
s = sNew;
}
}
class Second{
Simple simple;
String s;
public Second(String si) {
s = si;
}
public void chenked() {
if(simple==null) {
System.out.println("not initialized");
}else {
System.out.println("initialized");
}
}
private Simple lazy() {
if(simple==null) {
System.out .println("Creating simple");
simple = new Simple(s);
}
return simple;
}
public Simple getSimple() {
return lazy();
}
public String toString() {
return lazy().toString();
}
public void setSimple(String sNew) {
lazy().setString(sNew);
}
}
練習2:從Detergent中繼承產生一個新的類。覆蓋scrub()並新增一個名為sterilize()的新方法。
class Cleanser {
private String s = "Cleanser";
public void append(String a) { s += a; }
public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public String toString() { return s; }
public static void main(String[] args) {
Cleanser x = new Cleanser();
x.dilute(); x.apply(); x.scrub();
System.out.println(x);
}
}
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();
System.out.println(x);
System.out.println("Testing base class:");
Cleanser.main(args);
}
}
public class Exercise7_2 {
public static void main(String[] args) {
NewDetergent newDetergent = new NewDetergent();
newDetergent.dilute();
newDetergent.scrub();
newDetergent.sterilize();
System.out.println(newDetergent);
}
}
class NewDetergent extends Detergent{
public void scrub() {
append("new Detergent.scrub");
super.scrub();
}
public void sterilize() {
append("sterilize");
}
}
練習3:證明前面兩句話(即使你不為Cartoon建立構造器,編譯器也為會你合成一個預設的構造器,該構造器將呼叫基類的構造器)
public class Exercise7_3 {
public static void main(String[] args) {
new CartoonWithDefCtor();
}
}
class Art{
Art(){
System.out.println("Art constructor");
}
}
class Drawing extends Art{
Drawing(){
System.out.println("Drawing Contructor");
}
}
class CartoonWithDefCtor extends Drawing{
// public CartoonWithDefCtor() {
// System.out.println("CartoonWithDefCtor Contructor");
// }
}
練習4:證明基類構造器總是會被呼叫,在匯出類構造器之前被呼叫。
public class Exercise7_4 {
public static void main(String[] args) {
new Derived2();
}
}
class Base1{
public Base1() {
System.out.println("Base1");
}
}
class Derived1 extends Base1{
public Derived1() {
System.out.println("Derived");
}
}
class Derived2 extends Derived1{
public Derived2() {
System.out.println("Derived2");
}
}
練習5:建立兩個帶有預設構造器(空引數列表)的類A和類B。從A中繼承產生一個名為C的新,並在C內建立一個B類的成員。不要給C編寫構造器。建立一個C類的物件並觀察其結果。
public class Exercise7_5 {
public static void main(String[] args) {
new C();
}
}
class A{
public A() {
System.out.println("A");
}
}
class B{
public B() {
System.out.println("B");
}
}
class C extends A{
B b = new B();
}
練習6:用Chess證明前面兩名話
class Game {
Game(int i) {
System.out.println("Game constructor");
}
}
class BoardGame extends Game {
BoardGame(int i) {
super(i);
System.out.println("BoardGame constructor");
}
}
public class Exercise7_6 extends BoardGame {
Exercise7_6() {
super(11);
System.out.println("Chess constructor");
}
public static void main(String[] args) {
Exercise7_6 x = new Exercise7_6();
}
}
練習7:修改練習5,使A和B以帶引數的構造器取代預設的構造器。為C寫一個構造器,並在其中執行所有初始化。
public class Exercise7_7 {
public static void main(String[] args) {
new C(1);
}
}
class A{
public A(int i) {
System.out.println("A");
}
}
class B{
public B(String s) {
System.out.println(s);
}
}
class C extends A{
public C(int i) {
super(i);
B b = new B("s");
}
}
練習8:建立一個基類,它僅有一個非預設構造器;再建立一個匯出類,它帶有預設構造器和非預設構造器。在匯出類的構造器中呼叫基類的構造器。
public class Exercise7_8 {
public static void main(String[] args) {
new DerivedTwoContructors();
new DerivedTwoContructors(74);
}
}
class BaseNonDefault{
public BaseNonDefault(int i) {
}
}
class DerivedTwoContructors extends BaseNonDefault{
public DerivedTwoContructors() {
super(47);
}
public DerivedTwoContructors(int i) {
super(i);
}
}
練習9:建立一個Root類,令其含有名為Component1、Component 2、Component3的類的各一個例項(這些也由你寫)。從Root中派生一個類Stem,也含有上述各“組成部分”。所有的類都應帶有可打印出類的相關資訊的預設構造器
public class Exercise7_9 {
public static void main(String[] args) {
new Stem();
}
}
class Root{
Component1 c1 = new Component1();
Component2 c2 = new Component2();
Component3 c3 = new Component3();
public Root() {
System.out.println("Root");
}
}
class Stem extends Root{
Component1 c1 = new Component1();
Component2 c2 = new Component2();
Component3 c3 = new Component3();
public Stem() {
System.out.println("Stem");
}
}
class Component1{
public Component1() {
System.out.println("Component1");
}
}
class Component2{
public Component2() {
System.out.println("Component2");
}
}
class Component3{
public Component3() {
System.out.println("Component3");
}
}
練習10:修改練習9,使每個類都僅具有非預設的構造器。
public class Exercise7_10 {
public static void main(String[] args) {
new Stem2(1);
}
}
class Root2{
Componentb1 c1 = new Componentb1();
Componentb2 c2 = new Componentb2();
Componentb3 c3 = new Componentb3();
public Root2(int i) {
System.out.println("Root"+i);
}
}
class Stem2 extends Root2{
Componentb1 c1 = new Componentb1();
Componentb2 c2 = new Componentb2();
Componentb3 c3 = new Componentb3();
public Stem2(int i) {
super(i);
System.out.println("Stem2"+i);
}
}
class Componentb1{
public Componentb1() {
System.out.println("Component1");
}
}
class Componentb2{
public Componentb2() {
System.out.println("Component2");
}
}
class Componentb3{
public Componentb3() {
System.out.println("Component3");
}
}
練習11: 修改Detergent.java。讓它使用代理。
public class Exercise7_11 {
public static void main(String[] args) {
DetergentDelegation delegation = new DetergentDelegation();
delegation.append("Detergent");
System.out.println(delegation);
}
}
class Cleanser2 {
private String s = "Cleanser";
public void append(String a) { s += a; }
public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public String toString() { return s; }
}
class DetergentDelegation{
private Cleanser2 c = new Cleanser2();
public void append(String a) { c.append(a);}
public void dilute() {c.dilute(); }
public void apply() { c.apply(); }
public void scrub() { c.scrub(); }
public String toString() { return c.toString(); }
}
//Detergent.Java
class Cleanser {
private String s = "Cleanser";
public void append(String a) { s += a; }
public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public String toString() { return s; }
public static void main(String[] args) {
Cleanser x = new Cleanser();
x.dilute(); x.apply(); x.scrub();
System.out.println(x);
}
}
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();
System.out.println(x);
System.out.println("Testing base class:");
Cleanser.main(args);
}
}
練習12:將一個適當的dispose()方法的層次結構新增到練習9的所有類中。
public class Exercise7_12 {
public static void main(String[] args) {
new Stemc().dispose();
}
}
class Rootc{
Componentc1 c1 = new Componentc1();
Componentc2 c2 = new Componentc2();
Componentc3 c3 = new Componentc3();
public Rootc() {
System.out.println("Root");
}
public void dispose() {
System.out.println("Rootc.dispose()");
c1.dispose();
c2.dispose();
c3.dispose();
}
}
class Stemc extends Rootc{
Componentc1 c1 = new Componentc1();
Componentc2 c2 = new Componentc2();
Componentc3 c3 = new Componentc3();
public Stemc() {
System.out.println("Stem");
}
public void dispose() {
System.out.println("Rootc.dispose()");
c1.dispose();
c2.dispose();
c3.dispose();
super.dispose();
}
}
class Componentc1{
public Componentc1() {
System.out.println("Component1");
}
public void dispose() {
System.out.println("Componentc1.dispose()");
}
}
class Componentc2{
public Componentc2() {
System.out.println("Component2");
}
public void dispose() {
System.out.println("Componentc2.dispose()");
}
}
class Componentc3{
public Componentc3() {
System.out.println("Component3");
}
public void dispose() {
System.out.println("Componentc3.dispose()");
}
}
練習13: 建立一個類,它應帶有一個被過載了三次的方法。繼承產生一個新類,並新增一個該方法的新的過載定義,展示這四個方法在匯出類中都是可以使用的。
public class Exercise7_13 {
public static void main(String[] args) {
MoreOverloads moreOverloads = new MoreOverloads();
moreOverloads.f(1);
moreOverloads.f(1.1);
moreOverloads.f('c');
moreOverloads.f("Hello");
}
}
class ThreeOverLoads{
public void f(int i) {
System.out.println("f(int i)");
}
public void f(double d) {
System.out.println("f(double d)");
}
public void f(char c) {
System.out.println("f(char c)");
}
}
class MoreOverloads extends ThreeOverLoads{
public void f(String s) {
System.out.println("f(string s)");
}
}
練習14:在Car.java中給Engine新增一個service(),並在main()中呼叫該方法。
public class Exercise7_14 {
public static void main(String[] args) {
Car car = new Car();
car.left.window.rollup();
car.wheel[0].inflate(72);
car.engine.Service();
}
}
class Engine {
public void start() {}
public void rev() {}
public void stop() {}
public void Service() {
System.out.println("Engine.Service");
}
}
class Wheel {
public void inflate(int psi) {}
}
class Window {
public void rollup() {}
public void rolldown() {}
}
class Door {
public Window window = new Window();
public void open() {}
public void close() {}
}
class Car {
public Engine engine = new Engine();
public Wheel[] wheel = new Wheel[4];
public Door
left = new Door(),
right = new Door(); // 2-door
public Car() {
for(int i = 0; i < 4; i++)
wheel[i] = new Wheel();
}
}
練習15: 在包中編寫一個類,類應具備一個protected方法。在包外部,試著呼叫protede方法並解釋其結果。然後,從你的類中繼承產生一個類,並從該匯出類的方法內部呼叫該protected方法
練習16:建立一個名為Amphibian的類,由此繼承產生一個成為Frog的類,在基類中設定適當的方法,在main()中,建立一個Frog向上轉型至Amphibian, 然後說明所有方法都可工作。
public class Exercise7_16 {
public static void main(String[] args) {
Amphibian amphibian = new Frog();
amphibian.moveInWater();
amphibian.moveInLand();
}
}
class Amphibian{
public void moveInWater() {
System.out.println("moveInWater");
}
public void moveInLand() {
System.out.println("moveInLand");
}
}
class Frog extends Amphibian{
}
練習17:修改練習16,使Frog覆蓋基類中方法的定義。請留心main中都發生了什麼
public class Exercise7_17 {
public static void main(String[] args) {
Amphibian2 amphibian = new Frog2();
amphibian.moveInWater();
amphibian.moveInLand();
}
}
class Amphibian2{
public void moveInWater() {
System.out.println("moveInWater");
}
public void moveInLand() {
System.out.println("moveInLand");
}
}
class Frog2 extends Amphibian2{
public void moveInWater() {
System.out.println("Frog.moveInWater");
}
public void moveInLand() {
System.out.println("Frog.moveInLand");
}
}
練習18:建立一個含有static final域和final域的類,說明二者間的區別。
public class Exercise7_18 {
public static void main(String[] args) {
System.out.println("First Object");
System.out.println(new WithFinalFields());
System.out.println("Second Object");
System.out.println(new WithFinalFields());
}
}
class SelfCounter{
private static int count;
private int id = count++;
public String toString(){
return "Selfcounter"+id;
}
}
class WithFinalFields{
final SelfCounter selfCounter = new SelfCounter();
static final SelfCounter s = new SelfCounter();
public String toString(){
return "selfcounter = "+selfCounter+" \ns = "+s;
}
}
練習19 : 建立一個含有指向某物件的空白final引用類。在所有構造器內部都執行空白final的初始化操作。說明Java確保final在使用前必須初始化,且一旦被初始化即無法改變
public class Exercise7_19 {
public static void main(String[] args) {
WithFInalBlankField field = new WithFInalBlankField(10);
System.out.println(field.geti());
}
}
class WithFInalBlankField{
private final Integer i;
public WithFInalBlankField(int i1) {
i = new Integer(i1);
}
public Integer geti() {
// if(i==null) {
// i= new Integer(47);
// }
return i;
}
}
練習20:展示@Override註解可以解決本節中的問題
class WithFinals {
// Identical to "private" alone:
private final void f() { System.out.println("WithFinals.f()"); }
// Also automatically "final":
private void g() { System.out.println("WithFinals.g()"); }
}
class OverridingPrivate extends WithFinals {
private final void f() {
System.out.println("OverridingPrivate.f()");
}
private void g() {
System.out.println("OverridingPrivate.g()");
}
}
class OverridingPrivate2 extends OverridingPrivate {
public final void f() {
System.out.println("OverridingPrivate2.f()");
}
public void g() {
System.out.println("OverridingPrivate2.g()");
}
}
public class FinalOverridingIllusion {
public static void main(String[] args) {
OverridingPrivate2 op2 = new OverridingPrivate2();
op2.f();
op2.g();
// You can upcast:
OverridingPrivate op = op2;
// But you can't call the methods:
//! op.f();
//! op.g();
// Same here:
WithFinals wf = op2;
//! wf.f();
//! wf.g();
}
}
public class Exercise7_20 {
public static void main(String[] args) {
OverridingPrivate20 oPrivate = new OverridingPrivate20();
// oPrivate.f();
// oPrivate.g();
}
}
class OverridingPrivate20 extends WithFinals{
@Override private final void f() {
System.out.println("OverridingPrivate.f()");
}
@Override private void g() {
System.out.println("OverridingPrivate.g()");
}
}
class OverridingPrivate30 extends OverridingPrivate20{
@Override public void f() {
System.out.println("OverridingPrivate2.f()");
}
@Override public void g() {
System.out.println("OverridingPrivate2.g()");
}
}
練習21:建立一個但final方法的類。由此繼承產生一個類並嘗試覆蓋該方法
public class Exercise7_21 extends WithFinalMethod{
// void f() {
//
// }
public static void main(String[] args) {
}
}
class WithFinalMethod{
final void f() {
}
}
練習22: 建立一個final類並試著繼承它
public class Exercise7_22 extends FinalClass {
public static void main(String[] args) {
}
}
final class FinalClass{
}
練習23: 請證明載入類的動作僅發生一次。證明該類的第一個實體的建立者或者對static成員的訪問都有可能引起載入
public class Exercise7_23 {
public static void main(String[] args) {
System.out.println("Calling static member");
LoadTest.staticMember();
System.out.println("Creating an object");
new LoadTest();
}
}
class LoadTest{
static{
System.out.println("Loading loadTest");
}
static void staticMember() {};
}
練習24:在Beetle.java中,從Beetle類繼承產生一個具體型別的“甲殼蟲”。其形式與現有類相同,跟蹤並解釋其輸出結果
public class Exercise7_24 {
public static void main(String[] args) {
new JapaneseBeetle();
}
}
class JapaneseBeetle extends Beetle{
int m = printInit("JapaneseBeetle.m.initilized");
public JapaneseBeetle() {
System.out.println("m = "+m);
System.out.println("j = "+j);
}
static int x3 = printInit("static JapansesBeetle.x3 initlized");
}
//Beetle.java
class Insect {
private int i = 9;
protected int j;
Insect() {
System.out.println("i = " + i + ", j = " + j);
j = 39;
}
private static int x1 =
printInit("static Insect.x1 initialized");
static int printInit(String s) {
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
public Beetle() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}
private static int x2 =
printInit("static Beetle.x2 initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle();
}
} /* Output:
static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
*///:~