学习面向对象第三节

来源:互联网 发布:python 金融 pdf 编辑:程序博客网 时间:2024/06/04 08:18

1.引用变量的强制类型转换

public class ConverSionTest {public static void main(String[] args){double d=13.4;long l=(long)d;System.out.println(l);int in=5;//试图把一个数值类型的变量转换为boolean类型,下面代码编译出错//编译时会提示不可转换的类型//Boolean b=(Boolean)in;Object obj="Hello";//obj变量编译时类型是Object,Object和String存在继承的关系,可以强制类型转换//而且obj变量的实际类型是String,所以运行时也可以通过String objstr=(String)obj;System.out.println(objstr);///定义一个objPri变量,编译时类型是Object,实际类型是IntegerObject objPri=new Integer(5);//objPri变量编译时类型为Object,Object的运行时类型为Integer//Object与Integer存在继承关系//可以强制类型转换,而ObjPri变量的实际类型是Integer//所以下面的会引发ClassCastException异常//String str=(String)objPri;//考虑到强制类型转换时可能出现异常,因此进行类型转换之前应先通过instanceof运算符类判断是否可以成功转换。//为了让程序更加健壮,可以将代码修改为以下形式if(objPri instanceof String){String str=(String)objPri;}else{System.out.println("不可以进行强制类型转换");}}}
为了使程序更加的健壮,在强制类型转换之前,应该做一步判断,使用instanceof来判断该变量是否可以强制类型转换为另一种类型。从而避免出现ClassCastException异常,这样可以保证程序更加健壮。

注意:把子类对象赋给父类引用变量时,被称为向上转型(upcasting),这种转型总是可以成功。也从另一侧面证实子类是一种特殊的父类。

2.继承与组合

继承带来的高度复用的同时也带来了一个严重的问题:继承严重破坏了父类的封装性。前面介绍封装时提到了:每个类都应该封装他的内部类信息和实现细节,而只暴露必要的方法给其他类使用,但在继承关系中,子类可以直接访问,父类的成员变量和方法,从而造成子类和父类方法的严重耦合。

class Base{public Base(){test();}public void test(){System.out.println("将被子类重写的方法");}}public class Sub {private String name;public void test(){System.out.println("子类重写父类的方法"+"其name字符串长度"+name.length());}public static void main(String[] args){//会引发空指针异常Sub s=new Sub();System.out.println(s.name);s.name="asd";//在此处,如果没有设置name的值那么运行程序的时候会提示空指针异常,name的值为null,无法运行name.length()s.test();}}
为何要派生出子类?不仅需要保证子类是一种特殊的父类,而且需要具备以下几种基本特征条件之一

1)子类需要额外增加属性,而不仅仅是属性值的改变。例如从Person类派生出Student子类,Person类里没有提供grade(年级)属性,而Student类需要grade属性来保存student对象就读的年级,这种父类到子类的派生,就符合Java继承的前提

2)子类需要增加自己独有的行为方式(包括增加新的方法或者是重写父类的方法)例如从Person类派生出的Teacher类,其中Teacher类就需要增加一个teaching()方法,该方法用于描述Teacher对象独有的行为方式:教学。

3.利用组合实现复用

class Animals{    private void beat(){        System.out.println("心脏跳动……");    }    public void breath(){        beat();        System.out.println("吸一口气,吐一口气,呼吸中……");    }}class Bird{    //将原来的父类组合到原来的子类,作为子类的一个组合部分    private Animals a;    public Bird(Animals a){        this.a=a;    }    //重新定义一个自己的breath()方法    public void breath(){        //直接调用Animals提供breath()方法实现Bird的breath()方法        a.breath();    }    public void fly(){        System.out.println("我在天空自由地飞翔……");    }}class Wolf{    //将原来的父类组合到原来的子类中,作为子类的一个组合部分    private Animals a;    public Wolf(Animals a){        this.a=a;    }    //重新定义一个自己的breath()方法    public void breath(){        a.breath();    }    public void run(){        System.out.println("我在陆地上自由的奔跑……");    }}public class CompositeTest {    public static void main(String[] args){        Animals a1=new Animals();        Bird b=new Bird(a1);        b.breath();        b.fly();        //此时需要显式地创建被组合的对象        Animals a2=new Animals();        Wolf w=new Wolf(a2);        w.breath();        w.run();    }}
此时的Wolf对象和Bird对象由Animals对象组合而成,因此在上面程序创建的Wolf对象和Bird对象之前创建的Animals对象,并利用这个Animals对象来创建Wolf对象和Bird对象。


原创粉丝点击