第14章 抽象类和接口

来源:互联网 发布:tcp端口是什么 编辑:程序博客网 时间:2024/06/06 12:20
1、抽象类
     抽象类是重构的结果,在类头用abstract修饰;不能使用new操作符创建实例。抽象类的构造函数为protected  访问权限,因为它只被子类使用,创建一个具体子类的实例时,它的父类的构造方法被调用来初始化父类中定义的数据域。     
     抽象方法只有定义没有实现,它的实现由子类提供,一个包含抽象方法的类必须声明为抽象类,方法头用abstract修饰。抽象类和抽象方法在UML图中都为斜体。抽象方法只有声明没有实现且只能包含在抽象类中。抽象方法是非静态的。
     关于抽象类的几个关注点:
     ①抽象方法不能包含在非抽象类中,即抽象方法必须存在于抽象类中。在抽象类扩展的非抽象子类中,必须实现所有的抽象方法。另外,抽象方法是非静态的。
     ②抽象类是不能用new来初始化的,但是仍然可以定义它的构造方法,在子类的构造方法中调用。
     ③包含抽象对象的类必须是抽象的,但是可以定义一个不包含抽象方法的抽象类,这种类是用来定义新子类的基类的。
     ④即使子类的父类是具体的,该子类也可以为抽象类。
     ⑤子类可以覆盖父类的方法并将它定义为abstract。
     ⑥抽象类可以用作一中数据类型:
GeometriObject[ ] objects = new  GeometriObject[10];objects[0]  = new Cicle;  //注:Cicle是GeometriObject的子类





2、接口(interface)
     接口是设计的结果表明对象拥有某种属性
      Intanceof : 判断其左边对象是否为其右边类的实例,返回boolean类型的数据。可以用在继承中的子类的实例是否为父类的实现。
     接口可以作为一种数据类型:        
GeometriObject[ ] objects = new  GeometriObject[10];        objects[0]  = new Cicle;  //注: GeometriObject是Cicle的接口

或者    
Object[] objects = { new Tiger() , new Apple() };

            调用函数时候:(父类)objects.函数名();
     ①因为java不支持多重继承,所以有了接口,一个类只能继承一个父类,但可以实现多个接口,接口本身也可以继承多个接口(子接口)。
     ②接口里面的成员变量默认都是public static final类型的。必须被显示的初始化。
     ③接口里面的方法默认都是public abstract类型的。隐式声明。
     ④接口没有构造方法,不能被实例化。
     ⑤接口不能实现另一个接口,但可以继承多个接口。
     ⑥类如果实现了一个接口,那么必须实现接口里面的所有抽象方法,否则类要被定义为抽象类。
     ⑦接口都被编译为独立的字节码文件。
  

3、接口的三种使用: 可食用、可比较 、可克隆
      ①可食用:
   

     
     
      ②可比较(Comparable接口):
       

     
     ③可克隆(Cloneable接口):
      
      ※这个接口是空的,一个带空体的接口称为标记接口。一个标记接口不包括常量也不包括方法,它用来表示一个类拥有某些特定的属性。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用在Object类中定义的clone()方法克隆。
     
== 比较对象的引用   equals 比较内容
      
     ※在Object类中定义的clone方法的方法头:
            protected native Object clone( ) throw CloneNotSupportException;
            关键字native表示这个方法不是用Java写的,但是它是JVM针对自身平台实现的。
            关键字protected 限定方法只能在同一个包内或在其子类中使用。
            在覆盖clone()方法时候把修饰符改为public,就可以在任何一个包中使用,而调用super.clone()方法就可以完成克隆。
     
     ※浅复制与深复制
     浅复制:(浅克隆)在Object类中定义的clone方法将原始对象的每个数据域复制给目标对象。
          如果数据域是基本类型:复制值。
          如果数据域是引用类型:复制引用。
          被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

     深复制:(深克隆)
     被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

     ※Java的clone()方法
            clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
               ·对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象
               ·对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
               ·如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。

     ※Java中对象的克隆
          ·为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
          ·在派生类中覆盖基类的clone()方法,并声明为public。
          ·在派生类的clone()方法中,调用super.clone()。
          ·在派生类中实现Cloneable接口。

4、接口和抽象类的区别
     
     只允许为类的扩展做单一继承,但是允许使用接口做多重扩展。
     所有的类共享同一个根类Object,但是接口没有共同的根。
     接口只能包含抽象方法,抽象类可以包含普通方法。
     接口只能定义静态常量属性,抽象类既可以定义普通属性,也可以定义静态常量属性。
     接口不包含构造方法,抽象类里可以包含构造方法。    
     抽象类不能被实例化,但不代表它不可以有构造函数,抽象类可以有构造函数,备继承类扩充。
     接口可以定义不相关类共有的父类型,比类更加灵活。
        

     
     ※何时使用接口和抽象类:
          抽象类(父子关系): 强关系
          接口 :弱关系(类属关系)
     
     ※为什么接口要规定成员变量必须是public static final的呢?
      答:首先接口是一种高度抽象的"模版",,而接口中的属性也就是’模版’的成员,就应当是所有实现"模版"的实现类的共有特性,所以它是public static的 ,是所有实现类共有的 .假如可以是非static的话,因一个类可以继承多个接口,出现重名的变量,如何区分呢?
            其次,接口中如果可能定义非final的变量的话,而方法又都是abstract的,这就自相矛盾了,有可变成员变量但对应的方法却无法操作这些变量,虽然可以直接修改这些静态成员变量的值,但所有实现类对应的值都被修改了,这跟抽象类有何区别? 又接口是一种更高层面的抽象,是一种规范、功能定义的声明,所有可变的东西都应该归属到实现类中,这样接口才能起到标准化、规范化的作用。所以接口中的属性必然是final的。
            最后,接口只是对事物的属性和行为更高层次的抽象 。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则(Open-Closed Principle )的一种体现。

5、将基本数据类型作为对象处理
      Java提供一个方便的方法将基本数据类型并入对象或包装成对象,对应的类成为包装类。
      Double 、Float 、Long 、Integer 、Short 、Byte 继承Number类
      Number 、Character 、Boolean 继承Object类,所有类都实现Comparable接口。
      
      ①用基本数据类型值或者用表示数值的字符串来构造包装类          
        Double mydouble = new Double( 5.0);        Double mydouble = new Double( “5.0”);
     
      ②包装类没有无参构造方法,所有包装类的实例是不可变的,这意味着一旦创建对象后,它们内部的值就不可变。

     ③每个包装类都有MAX_VALUE、MIN_VALUE 、
            MAX_VALUE 表示对应的基本数据类型的最大值。
            MIN_VALUE 对于Long 、Integer 、Short 、Byte表示long 、int 、short 、byte基本数据类型的最小值
            MIN_VALUE 对于Double 、Float 表示 double 、float基本数据类型的最小正值。

     ④数值包装类有个静态方法 valueOf( String s ) :创建一个对象并初始化为指定字符串表示的值。
            Double mydouble = valueOf( ( “5.0”);

     ⑤Integer.parseInt()
        int x = Integer.parseInt(s);  //将字符串值转换为基本类型值        Integer.parseInt(“s” , 2/8/10/16)    //将数值字符串s 转换为2/8…进制的数值


6、基本类型与包装类类型之间的自动转换
      Integer intArray = new Integer {1,2,3};                        //自动装箱      System.outt.printlin(intArray[0] + intArray[1] + intArray[2]);      //自动开箱


7、BigInteger 和 BigDecimal 类
     进行非常大的数的计算或者高精度浮点值的计算
     算术运算:add 、subtract 、multiply 、divide 和 remainder   
      BigInteger a = new BigInteger (“10”);      BigInteger b = new BigInteger(“99999999999999999999999”);      a.multiply(b);  相乘      BigDecimal a = new BigDecimal (“.10”);      BigDecimal b = new BigDecimal (“3”);      a.divide(b,20, BigDecimal.ROUND_UP);  //相除  0.3333333333333333334      // BigDecimal.ROUND_UP向上约等于、 20 表示小数点后的位数


0 0
原创粉丝点击