Java面向对象编程-第11章学习笔记

第11章 对象的生命周期
一、创建对象的方式
4种显式地创建对象的方式:
(1)用new语句创建对象;
(2)运用反射手段;
(3)调用对象的clone()方法;
(4)运用反序列化手段。


public class Customer implements Cloneable{
    private String name;
    private int age;

    public Customer(){
        this("unknown",0);
        System.out.println("call default constructor");     
    }

    public Customer(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("call second constructor");
    }

    public Object clone()throws CloneNotSupportedException{
        return super.clone();
    }

    public boolean equals(Object o){
        if (this==o)
            return true;
        if(!(o instanceof Customer))
            return false;
        final Customer other=(Customer)o;
        if(this.name.equals(other.name)&&this.age==other.age)
            return true;
        else
            return false;
    }

    public String toString(){
        return "name="+name+",age="+age;
    }

    public static void main(String args[])throws Exception{
        //运用反射手段创建对象
        Class objClass=Class.forName("Customer");

        Customer c1=(Customer)objClass.newInstance();  //这里会调用默认构造方法
        System.out.println("c1: "+c1);

        //用new语句创建对象
        Customer c2=new Customer("Tom",20);
        System.out.println("c2:  "+c2);

        //运用克隆手段创建对象
        Customer c3=(Customer)c2.clone();    //这里不会调用Customer的构造方法
        System.out.println("c2==c3 :  "+(c2==c3));
        System.out.println("c2.equals(c3) :  "+c2.equals(c3));
        System.out.println("c3:  "+c3);
    }
}

打印结果如下:

call second constructor
call default constructor
c1: name=unknown,age=0
call second constructor
c2:  name=Tom,age=20
c2==c3 :  false
c2.equals(c3) :  true
c3:  name=Tom,age=20

二、构造方法
构造方法负责对象的创建工作,并为其实例变量赋予合适的初始值。必须满足以下语法规则:
(1)方法名必须与类名相同。
(2)不要声明返回类型。
(3)不能被static/final/synchronized/abstract/native修饰。构造方法不能被子类继承。
1、重载构造方法
示例:

public class Employee{
    private String name;
    private int age;

    //当雇员姓名和年龄已知
    public Employee(String name,int age){
        this.age=age;
        this.name=name;
    }

    //当雇员姓名已知,而年龄未知
    public Employee(String name){
        this(name,-1);//调用上一个构造函数,用-1表示年龄未知
    }

    //当雇员姓名和年龄都未知
    public Employee(){
        this("无名氏");
    }

    public void setName(String name){
        this.name=name;
    }
    public void setAge(int age){
        this.age=age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
}

以下程序分别通过3个构造方法创建了3个Employee对象

Employee zhangsan=new Employee("zhangsan",25);
Employee lisi=new Employee("lisi");
Employee someone=new Employee();

关于this语句的用法必须注意:
(1)如果在构造方法中使用this语句,那它必须作为该方法的第一条语句。
(2)只能在构造方法中使用this语句调用类的其他构造方法,不能在类的实例方法中使用。

2、默认构造方法
默认构造方法是指没有参数的构造方法,分为两种:
(1)隐式包含的默认构造方法。
当类的定义中没有任何显式的构造方法(无参或有参)时,则系统默认会给该类一个隐式的无参构造方法。
(2)显式定义的默认构造方法。
当类中显式定义了一个无参构造方法。

要注意的是:当类中显式定义了一个或多个构造方法,并且所有构造方法都带参数,则这个类就失去了默认构造方法。

3、子类调用父类的构造方法
父类的构造方法不能被子类继承,如MyException类继承了java.lang.Exception类:

public class MyException extends Exception{}

上述MyException只有一个隐式的默认构造方法。虽然Exception类用如下的构造方法:

public Exception(String msg){...}

但Myexception是无法继承该构造方法的,以下代码编译出错:

MyException myExcp=new MyException("Hey,Error!");

但是,在子类的构造方法中,可以通过super语句调用父类的构造方法,比如:

public MyException(){
    super("something is error");
}
public MyException(String msg){
    super(msg);
}

用super语句来调用父类的构造方法,必须遵守以下规则:
(1)在子类构造方法中,不能直接通过父类方法名调用父类构造方法,而必须用super。
(2)当使用super语句调用父类构造方法时,它必须作为构造方法的第一条语句。

在创建子类对象时,Java虚拟机先执行父类构造方法,再执行子类构造方法,在多级继承中,将从继承树最上层父类开始依次执行各个类的构造方法,如下例:


public class Base{
    private int a;
    public Base(int a){
        this.a=a;
        System.out.println("父类Base有参构造函数执行了!");
    }
    public int getA(){
        return this.a;
    }
}

public class Test extends Base{
    private int b;
    public Test(int a,int b){
        super(a);
        this.b=b;
        System.out.println("子类Test有参构造函数执行了");
    }
    public int getB(){
        return this.b;
    }

    public static void main(String[] args){
        Test test=new Test(1,2);
        System.out.println("a="+test.getA()+" b="+test.getB());     
    }
}

输出如下:

父类Base无参构造函数执行了!
子类Test有参构造函数执行了
a=0 b=2

4、构造方法的作用域
构造方法只能通过以下方式被调用:
(1)当前类的其他构造方法通过this语句调用它;
(2)当前类的子类的构造方法通过super语句调用它;
(3)在程序中通过new语句调用它。

5、构造方法的访问级别
构造方法可以处于public/protected/private和默认中之一,当构造方法为private级别时,意味着只能在当前类中访问它:在当前类的其他构造方法中可以通过this语句调用,也可以在当前类的成员方法中通过new语句调用它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值