5. 封装和继承

来源:互联网 发布:q版养成网络手游 编辑:程序博客网 时间:2024/06/05 20:11

一、初始化块

        注意:类中块的执行位置是全局变量之后构造体内的其他语句之前

二、对象的初始化过程

  1. 设置实例变量的值为缺省的初始值
  2. 调用对象的构造器 ,绑定构造器参数。
  3. 如果构造器中有this()调用,则根据this()调用的参数调用相应的重载构造器,然后,转到步骤5;否则转到步骤4。
  4. 除java.lang.Object类外,调用父类的中的初始化块初始化父类的属性,然后调用父类构造器,如果在构造器中有super()调用,则根据super()中的参数调用父类中相应的构造器。
  5. 使用初始化程序和初始化块初始化成员。
  6. 执行构造器方法体中其他语句。

三、封装类

对于简单数据类型数据,为了和Java面向对象的思路一致,
    Java为每一个内置数据类型提供了对应的包装类。
    内置类型                封装类型
简单数据类型
封装类
boolean
Boolean
byte
Byte
int
Integer
long
Long
char
Character
float
Float
double
Double

   每个简单类型都有一个对应的封装类,可以使用封装类的方法
      System.out.println((int)Character.MIN_VALUE+"-"+(int)Character.MAX_VALUE);
      System.out.println(Integer.SIZE);
      Integer i=new Integer(100);
      System.out.println(Integer.toBinaryString(i));
     System.out.println(Integer.toOctalString(i));

装箱:把简单类型封装成对应的引用类型
       Integer i1 = 100;  
       Integer i2 = 100;//Integer.valueof(100)  跟valuedof的源码,看原理
            ---100这里相当于调用了Integer.valueof(100)的方法
       i1 == i2 ? 相等    相等,原因是,在数值在范围内的数据,是先开辟堆上的空间缓存池cache,i1和i2是栈上的地址,地址相同,不会再开辟新的空间。

    这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,

    编译器也可以把一个对象拆箱为内置类型。Number类属于java.lang包。

    包装类遇到内置数据类型

    public class Test{

       public static void main(String args[]){

          Integer x = 5; // boxes int to an Integer object

                //上边的的语句相当于 Integer x = 

          x =  x + 10;   // unboxes the Integer to a int

          System.out.println(x);

       }

    }


      问题:       Integer i1 = 200;  
                   Integer i2 = 200;
                   i1 == i2 ? 不相等   缓存池中放了256个Short,值是-128~127


需要注意的地方:
    boolean类型的值
    所有byte类型的值
    在-128~127之间的short类型的值
    在-128~127之间的int类型的值
   在\u0000~\u007F之间的char类型的值
   float和double不在缓存池    

       ----拆箱:封装类遇到了简单类型,自动拆箱
     
        Short s1 = 19;
        short s2 = 19;
        s1 == s2 ?  相等  比较的数值 (先拆箱,再比较值)
        s1 + 10 = ?  29 (先拆箱,再运算)

四、static关键字  

     对象是类的实例 --没有static修饰的..是实例..?

    ---修饰属性
       ---实例属性:普通属性,每个对象都存储一份
       ---静态属性:static修饰的属性,该类的所有对象共用一份数据
       若属性的访问修饰符,不是private
       同包下的类可以通过   类名.属性 访问

     问题1:实例方法能否访问静态属性?  可以

     问题2:静态方法能否访问实例属性?不可以
            结论:静态方法只能访问类中的静态属性


   ----static初始化块,只在类加载时执行一次,只能对静态成员初始化(不能对实例成员初始化)

五、final: --声明final方法的主要目的是防止该方法的内容被修改

①final修饰属性
      第一种写法:final属性定义时初始化
      第二种写法:final属性定义时不初始化,每一个构造器都需要给final属性初始化
      结论:在初始化后不可改变变(只能初始化一次)

②final修饰局部变量
      变量只能赋值一次(相当于常量)
        

        Final变量能被显式地初始化并且只能初始化一次。被声明为final的对象的引用不能指向不同的对象。

        但是final对象里的数据可以被改变。也就是说final对象的引用不能改变,但是里面的值可以改变。

        Final修饰符通常和static修饰符一起使用来创建类常量。

 

③final修饰方法:该方法不能被覆盖(子类不能重新实现)
            或者说 类中的Final方法可以被子类继承,但是不能被子类修改。

④final修饰:该类不能被继承,没有类能够继承final类的任何特性。
     
   public final class Integer {
       public static final int MAX_VALUE;
           ......
   }

六、抽象类: --abstract

  • 抽象方法:类中没实现的方法,会有abstract修饰
  • 抽象:有abstract修饰的类,叫抽象类  
在以下任一条件成立时,类必须定义成抽象类:
    类中有至少一个抽象方法
    类继承了父类中的抽象方法,但是至少有一个抽象方法没有实现
    类实现了某个接口,但没有全部实现接口中的方法

抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供

    抽象方法不能被声明成final和strict。

   任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

   如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。

   抽象方法的声明以分号结尾,例如:public abstract sample();

七、接口: --implements,interface

   没有实现的接口不能实例化
   当声明了一个接口,然后实例化他,会相应的自动补全他未实现的方法。这种就叫做
        匿名内部类(Anonymous Inner Class);
        这种方法的好处是可以多次使用接口,然后在不同的地方实现不同的功能。

   所有属性都是pulic final static 属性(常量),pulic final static关键字可以省略
   所有方法都是pulic abstract方法,pulic abstract关键字可以省略

   类可以实现多个接口
   ---若多个接口有相同的属性,怎么调用?接口名.属性名
      System.out.println(ICommTool.name);
      System.out.println(IMediaPlayer.name);

八、多态

    父类的引用指向子类的对象
    ---用父类的引用调用方法,只能调用父类声明过的方法
    ---若想调用子类新增加的方法,使用强制类型换
    ---若想避免强制类型转换异常,使用instanceof

         Animal animal = new Dog();
         if(animal instanceof Cat) {
             ((Cat)animal).catchMouse();
          } else {
                  System.out.println("不是Cat类的对象");
              }  
          }

例子:

    父类引用子类对象。

   

   animal是父类,cat和dog是子类,子类中有不一样名字的方法。则多态的体现是

     Animal animal = new Cat();

     animal.weizhi();

 

     animal = new Dog();

     animal.weizhi();

   父类调用子类中特殊的方法是:

     ((Dog)animal).dongzuo();



    Java中没有多继承的原因是:
    有钻石危机现象:
        假设 类A中有一个public方法fun(),然后类B和类C同时继承了类A,
        在类B或类C中各自对方法fun()进行了覆盖,这时类D通过多继承
        同时集成了类B和类C,这样便导致钻石危机了,程序在运行的时候
        对于方法fun()该如何判断的问题。

初始化块:
    执行的位置是在构造器之前,每次调用构造器的时候,都会执行初始化块

this();
    是调用本对象的构造器。
   

static

有static的方法,在调用的时候用方法名来调用
final

Final变量:

   Final变量能被显式地初始化并且只能初始化一次。被声明为final的对象的引用不能指向不同的对象。但是final对象里的数据可以被改变。也就是说final对象的引用不能改变,但是里面的值可以改变。

   Final修饰符通常和static修饰符一起使用来创建类常量。

Abstract抽象类

抽象类:

   抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

   一个类不能同时被abstract和final修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。

   抽象类可以包含抽象方法和非抽象方法。

0 0
原创粉丝点击