java的学习记录8


第7章 复用类

java通过创建新类复用代码,还可以使用别人开发好的类。


组合和聚合 。参考:http://blog.csdn.net/liushuijinger/article/details/6994265


方法1:在新的类中创建已有类的对象。谓之组合。

方法2:按照已有类创建新类。位置继承。

7.1 组合语法

例子:

class WaterSource{  //水源
        private String s;
        WaterSource(){
                System.out.println("WaterSource()");
                s="constructed";
        }
        public String toString(){return s;}
}
public class SprinklerSystem{ // 洒水系统
        private String valve1,valve2,valve3,valve4;
        private WaterSource source=new WaterSource();
        private int i;
        private float f;
        public String toString(){
                return
                        "valve1="+valve1+" "+
                        "valve2="+valve2+" "+
                        "valve3="+valve3+" "+
                        "valve4="+valve4+"\n"+
                        "i="+i+" "+"f="+f+" "+"source="+source;
        }
        public static void main(String[] args){
                SprinklerSystem sprinkler=new SprinklerSystem();
                System.out.println(sprinkler);
        }
}

结果:

WaterSource()
valve1=null valve2=null valve3=null valve4=null
i=0 f=0.0 source=constructed

分析:

要点1:在类SprinklerSystem中,有一个方法toString().每一个非基本类型的对象都有一个toString()方法,而且当编译器需要一个String而程序中只有一个对象时,该方法会被调用。所以SprinklerSystem.toString()的程序段“  “source=”+source; ”中,编译器会将字符串source=  和类WaterSource的对象source相加。这里对象source会转变为String类型。

要点2:类中域为基本类型时,编译器会自动初始化为0;但是如果是一个对象引用,会初始化NULL,调用方法会产生异常。



可以在以下4个位置初始化引用。

1.在定义对象的地方。这意味着它们总能够在构造器被调用之前被初始化。

2.在类的构造器中。

3.在将要使用这些对象之前,谓之惰性初始化。

4.直接实例初始化。

class Soap{  //肥皂
        private String s;
        Soap(){
                System.out.println("Soap()");    //2.
                s="constructed";
        }
        public String toString(){
                return s;
        }
}
public class Bath{  //浴室
        private String s1="happy",s2="happy2",s3,s4;
        private Soap castille;
        private int i;
        private float toy;
        public Bath(){
                System.out.println("Bath()");
                s3="joy";
                toy=3.14f;
                castille=new Soap();   //1.
        }
        {i=47;}
        public String toString(){
                if(s4==null)
                  s4="joy";    //3.
                return
                        "s1="+s1+"\n"+
                        "s2="+s2+"\n"+
                        "s3="+s3+"\n"+
                        "s4="+s4+"\n"+
                        "i="+i+"\n"+
                        "toy="+toy+"\n"+
                        "castille="+castille;
        }
        public static void main(String[] args){
                Bath  b=new Bath();   //4.
                System.out.println(b);
        }
}

结果:

Bath()
Soap()
s1=happy
s2=happy2
s3=joy
s4=joy
i=47
toy=3.14
castille=constructed


分析:

在类Bath的方法toString()被调用之前,s4会被初始化。


7.2  继承语法

所有的类都是从根类Object继承,使用关键字extends.

例子:

class Cleanser{  //清洁器
        private String s="Cleanser";
        public void append(String a){
                s+=a;
        }
        public void dilute(){
                append("dilute()");
        }
        public void apply(){
                append("append()");
        }
        public void scrub(){
                append("scrub()");
        }
        public String toString(){
                return s;
        }
        public static void main(String[] args){
                Cleanser c=new Cleanser();
                c.dilute();
                c.apply();
                c.scrub();
                System.out.println(c);
        }
}
public class Detergent extends Cleanser{  //洗衣粉
        public void scrub(){
                append("Detergent.scrub()");
                super.scrub();
        }
        public void foam(){
                append("foam()");
        }
        public static void main(String[] args){
                Detergent d=new Detergent();
                d.dilute();
                d.apply();
                d.scrub();
                d.foam();
                System.out.println(d);
                Cleanser.main(args);   //输出基类的main函数
        }
}

结果:

Cleanserdilute()append()Detergent.scrub()scrub()foam()
Cleanserdilute()append()scrub()

分析:

要点1: 在类Cleanser中,方法append()用“+=”链接字符串。或者“+”

要点2:类Cleanser和类Detergent都含有main()方法。便于单元测试。

要点3:类Cleanser中的方法都是public。

要点4:类Detergent中方法scrub(),super.scrub()会调用基类方法。


例子:子类初始化与基类的先后关系

class Art{
        Art(){
                System.out.println("Art constructor");
        }
}
class Drawing extends Art{
        Drawing(){
                System.out.println("Drawing constructor");
        }
}
public class Cartoon extends Drawing{
        public Cartoon(){
                System.out.println("Cartoon constructor");
        }
        public static void main(String[] args){
                Cartoon c=new Cartoon();
        }
}

结果:

Art constructor
Drawing constructor
Cartoon constructor

分析:

构建过程从基类到子类。


7.3 代理

结合 继承 和 组合 的折中方法,将一个对象至于新类中(类似组合),同时在新类中暴露 对象的所有方法(类似继承)。


例子:太空的控制模块的方法如下

public class SpaceShipControls{
        void up(int velocity){}    ///速度
        void down(int velocity){}
        void left(int velocity){}
        void right(int velocity){}
        void forward(int velocity){}
        void back(int velocity){}
        void turboBoost(){}
}

使用继承构造太空船。

public class SpaceShip extends SpaceShipControls{
        private String name;
        public SpaceShip(String name){
                this.name=name;
        }
        public String toString(){
                return name;
        }
        public static void main(String[] args){
                SpaceShip spaceship=new SpaceShip("NSE"); 
                spaceship.forward(100);
        }
}
 

编译:若缺少“NSE”,出错。

SpaceShip.java:10: 错误: 无法将类 SpaceShip中的构造器 SpaceShip应用到给定类型;
                SpaceShip spaceship=new SpaceShip();
                                    ^
  需要: String
  找到: 没有参数
  原因: 实际参数列表和形式参数列表长度不同
1 个错误

使用代理:

public class SpaceShipDelegation{
        private String name;
        private SpaceShipControls controls=new SpaceShipControls();
        public SpaceShipDelegation(String name){
                this.name=name;
        }

        public void back(int velocity){
                controls.back(velocity);
        }
        public void down(int velocity){
                controls.down(velocity);
        }
        public void forward(int velocity){
                controls.forward(velocity);
        }
        public void left(int velocity){
                controls.left(velocity);
        }
        public void right(int velocity){
                controls.right(velocity);
        }
        public static void main(String[] args){
                SpaceShipDelegation protector=new SpaceShipDelegation("NSEA");
                protector.forward(100);
        }
}

7.4  结合使用组合和继承





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值