2015年11月26日 Java基础系列(四)class的定义,继承和实现interface 一、类定义中的变量 二、类定义中的方法 三、如何将实参的值传递给方法 四、Final形参 五、初始化数据成员 六、重写finalize 七、类的继承 八、多态  九、抽象类 十、通用超类Object 十一、final关键字 十二、接口

2015年11月26日 Java基础系列(四)class的定义,继承和实现interface
一、类定义中的变量
二、类定义中的方法
三、如何将实参的值传递给方法
四、Final形参
五、初始化数据成员
六、重写finalize
七、类的继承
八、多态
 九、抽象类
十、通用超类Object
十一、final关键字
十二、接口

序,类的设计是JAVA操作的核心,面对对象思想中一切皆对象。

静态成员变量,为类所有,称为类变量;只有一份,编译时即分配值,使用关键字static声明。

非静态成员变量,每个实例一份。称为实例变量。

二、类定义中的方法

与变量类似,方法也分为类方法和实例方法。

类方法,拥有关键字static声明,即类还没有实例化之前就可以执行。

实例方法,必须类实例化之后才能使用该方法。

三、如何将实参的值传递给方法

通过使用值传递的机制将所有实参的值传递给方法,具体来说,对于基本类型(int,float,double,char,String等)都是传递一个副本值给形参,但是对于类对象(StringBuffer,自定义类等)则是传递一个引用给形参。

这也就意味着,如果在方法体内对基本类型的形参的操作不会引起实参的改变。但是对引用类型的形参的操作会更改实参的值。

public static void main(String[] args) {
        StringBuffer a = new StringBuffer("a");
        changeValue(a);//会把a也改变
        System.out.println(a.toString());
    }
    
    private static void changeValue(StringBuffer b) {
        b = b.append("b");
        System.out.println(b.toString());
    }
public static void main(String[] args) {
        String a = "a";
        changeValue(a);//不会改变a的值,a依然为“a”
        System.out.println(a.toString());
    }
    
    private static void changeValue(String b) {
        b = "b";
        System.out.println(b.toString());
    }

四、Final形参

防止你在调用该方法时修改形参的值,也会对实参的值进行改变。

final实际上只在应用于引用类对象的形参时有意义。

关键字final的一个更重要的作用是将类或者方法声明为final。

五、初始化数据成员

使用初始化快

静态初始化块:是使用static定义的代码块,当类装载到系统时将执行一次。静态初始化块只能初始化类的静态数据成员。

非静态初始化块:对每个要生成的对象执行一次,可以初始化类的实例变量。

 六、基本数据类型的标准类与自动装箱、拆箱

Boolean Character Byte Short Integer Long Float Double为基本类型的类类型

编译器由基本类型自动转换成标准类类型的过程被称为自动装箱,反之为自动拆箱。

六、重写finalize

System.runFinalization();//会调用类的finalize()方法,释放类的资源
System.gc();//调用JVM的垃圾回收器

@Override
protected void finalize() {}//重写Object的finalize()方法,此方法是在GC回收此对象前执行的方法,可以做些清理资源的操作。

七、类的继承

下面这个例子中有几个点需要注意:

Animal构造函数与子类Dog的构造函数存在一定关系。

(1)如果Animal无构造函数,则系统默认为之添加默认构造函数(即无参构造函数),Dog则无任何约束。

(2)如果Animal存在有参构造函数,则Dog必须显示声明构造函数,且第一句必须显示调用父类构造函数(利用super关键字)。

(3)如果父类重写了toString方法,子类没有显示重写toString方法,则输出子类时直接调用父类的toString方法。

//Animal.java
package com.ycc.home;

public class Animal {
    private String type;

    public Animal(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Animal [type=" + type + "]";
    }

}
//Dog.java
package com.ycc.home;

public class Dog extends Animal {
    private String name;
    private String breed;

    public Dog(String name, String breed) {
        super(name);
        this.name = name;
        this.breed = breed;
    }

    public Dog(String name) {
        super(name);
        this.name=name;
        breed="unknown";
    }

}
//TestAnimail.java
package com.ycc.home;

public class TestAnimal {
    public static void main(String[] args) {
        Dog dog1 = new Dog("fido");
        Dog dog2 = new Dog("Lassie", "China");
        System.out.println(dog1);
        System.out.println(dog2);
    }
}

//输出
Animal [type=fido]
Animal [type=Lassie]

八、多态

多态只作用于方法,而不作用于数据成员

调用的方法必须在派生类中被定义

基类和派生类中对应方法的签名必须相同

基类和派生类的方法的返回对象类型必须相同或者返回对象类型是协变

举例:

Animal dog = new Dog("fido");
Animal cat = new Cat("Lassie", "China");
dog.sound();//Dog类的sound方法
cat.sound();//Cat类的sound方法

 九、抽象类

其实,抽象类的产生是为了使用多态的一种手段。

1 抽象类中不一定有抽象方法,抽象类用abstract修饰。

2 有抽象方法的类一定是抽象类,抽象方法用abstract修饰。

3 抽象类是不能被实例化的,抽象类就是被继承的。

4 抽象类的子类如果没有全部实现父类的抽象方法,那么子类也是抽象的,直到全部实现父类的抽象方法才可实例化。

5 一个abstract方法不能声明为private的,因为private方法不能被继承。

举例:

package com.ycc.home;

public abstract class Animal {
    private String type;

    public Animal(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Animal [type=" + type + "]";
    }

    public abstract void sound();
}

十、通用超类Object

1 、下面7个是public的

toString()  返回格式为:类名@十六进制(hashCode)类名中包括包名,例如:com.ycc.home.Dog@139a55

equals()  实参的引用与当前对象的引用是指向同一个对象,则为true,否则为false

getClass() 返回一个Class类型的对象,以识别当前对象所属的类。

hashCode() 计算当前对象的散列值(hashcode)

notify() 用于唤醒一个与当前对象关联的线程

notifyAll() 用于唤醒所有与当前对象关联的线程

wait() 该方法导致一个线程等待当前对象中发生的变化。

2 、下面两个是protected的

clone() 生成一个对象,是当前对象的一个副本,而不管该对象的类型。

finalize() 在销毁对象时被调用,用于清理工作

源码如下:

package java.lang;

public class Object
{
  private static native void registerNatives();
  
  public final native Class<?> getClass();
  
  public native int hashCode();
  
  public boolean equals(Object paramObject)
  {
    return this == paramObject;
  }
  
  protected native Object clone()
    throws CloneNotSupportedException;
  
  public String toString()
  {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
  }
  
  public final native void notify();
  
  public final native void notifyAll();
  
  public final native void wait(long paramLong)
    throws InterruptedException;
  
  public final void wait(long paramLong, int paramInt)
    throws InterruptedException
  {
    if (paramLong < 0L) {
      throw new IllegalArgumentException("timeout value is negative");
    }
    if ((paramInt < 0) || (paramInt > 999999)) {
      throw new IllegalArgumentException("nanosecond timeout value out of range");
    }
    if (paramInt > 0) {
      paramLong += 1L;
    }
    wait(paramLong);
  }
  
  public final void wait()
    throws InterruptedException
  {
    wait(0L);
  }
  
  protected void finalize()
    throws Throwable
  {}
  
  static {}
}

十一、final关键字

1 方法定义时声明为final的,则子类就无法覆盖此方法。

2 定义类时声明为final的,则此类就不能被继承。

3 抽象类不能声明为final,因为抽象类天生用来继承的。

4 抽象方法不能声明为final,因为抽象方法就是用来被覆盖的。

十二、接口

接口实际上是一组相关常量和(或)抽象方法

1 接口中的常量在默认状态下总是public、static和final类型的

2 接口中的方法在默认状态下总是public和abstract类型的

3 如果读者没有实现接口中声明的所有方法,则必须将该类声明为abstract.

4 静态导入,import static 包名.类名.*;

5 接口扩展:extends接口

6 多重接口,extends多个接口

7 接口的作用:利用接口实现多态

8 匿名类、嵌套类