zoukankan      html  css  js  c++  java
  • 构造方法

    构造方法

    构造方法的格式:

    修饰符 构造方法名(参数列表)
    
    {
    
    }

     构造方法的体现

       构造方法没有返回值类型。也不需要写返回值。因为它是为构建对象的,对象创建完,方法就执行结束。

      构造方法名称必须和类名保持一致。

       构造方法没有具体的返回值。

    构造方法的代码体现

    class Person {
        // Person的成员属性age和name
        private int age;
        private String name;
    
        // Person的构造方法,拥有参数列表
        Person(int a, String nm) {
            // 接受到创建对象时传递进来的值,将值赋给成员属性
            age = a;
            name = nm;
        }
    }

     构造方法调用和内存图解

    理解构造方法的格式和基本功能之后,现在就要研究构造方法是怎么执行的呢?在创建对象的时候是如何初始化的呢?

             构造方法是专门用来创建对象的,也就是在new对象时要调用构造方法。现在来看看如何调用构造方法。

    class Person {
        // Person的成员属性age和name
        private int age;
        private String name;
    
        // Person的构造方法,拥有参数列表
        Person(int a, String nm) {
            // 接受到创建对象时传递进来的值,将值赋给成员属性
            age = a;
            name = nm;
        }
    
        public void speak() {
            System.out.println("name=" + name + ",age=" + age);
        }
    }
    
    class PersonDemo {
        public static void main(String[] args) {
            // 创建Person对象,并明确对象的年龄和姓名
            Person p2 = new Person(23, "张三");
            p2.speak();
        }
    }

    上述代码演示了创建对象时构造方法的调用。即在创建对象时,会调用与参数列表对应的构造方法。

    内存图解:

     图解说明:

      1、首先会将main方法压入栈中,执行main方法中的 new Person(23,"张三");

      2、在堆内存中分配一片区域,用来存放创建的Person对象,这片内存区域会有属于自己的内存地址(0x88)。

        然后给成员变量进行默认初始化(name=null,age=0)。

      3、执行构造方法中的代码(age = a ; name = nm;),将变量a对应的23赋值给age,将变量nm对应的”张三赋值给name,

        这段代码执行结束后,成员变量age和name的值已经改变。执行结束之后构造方法弹栈,Person对象创建完成。

        将Person对象的内存地址0x88赋值给p2。

     构造方法注意:

      构造方法调用,创建对象的时候调用,而且一个对象只调用一次
      调用完构造方法以后分配地址,在创建对象方法后,赋值
      构造方法,类里面一个构造方法也没有,那么这个类在编译的时候,编译器会自动给你添加一个空参构造方法,如果有,那么编译器就不给添加了
      在添加构造方法,另外写一个空参构造方法

      一个类中可以有多个构造方法,多个构造方法是以重载的形式存在的

      构造方法是可以被private修饰的,作用:其他程序无法创建该类的对象。

      例如:

    class Person {
        private int age;
        private String name;
    
        // 私有无参数的构造方法,即外界不能通过new Person();语句创建本类对象
        private Person() {
        }
    
        // 多个构造方法是以重载的形式存在
        Person(int a) {
            age = a;
        }
    
        Person(String nm, int a) {
            name = nm;
            age = a;
        }
    }

     this调用构造方法

    构造方法调用格式:

    this(参数列表);

     构造方法的调用

    例子:

    class Person {
        // Person的成员属性
        private int age;
        private String name;
    
        // 无参数的构造方法
        Person() {
        }
    
        // 给姓名初始化的构造方法
        Person(String nm) {
            name = nm;
        }
        // 给姓名和年龄初始化的构造方法
        Person(String nm, int a) {
            // 由于已经存在给姓名进行初始化的构造方法 name = nm;因此只需要调用即可
            // 调用其他构造方法,需要通过this关键字来调用
            this(nm);
            // 给年龄初始化
            age = a;
        }
    }

    super关键字

    在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句。

    格式:

    调用本类中的构造方法
      this(实参列表);
    调用父类中的空参数构造方法
      super();
    调用父类中的有参数构造方法
      super(实参列表);

    为什么子类对象创建都要访问父类中的构造方法?因为子类继承了父类的内容,所以创建对象时,必须要先看父类是如何对其内容进行初始化的,看如下程序:

    public class Test {
        public static void main(String[] args) {
            new Zi();
        }
        
    }
    class Fu{
        int num ;
        Fu(){
            System.out.println("Fu构造方法"+num);
            num = 4;
        }
    }
    class Zi extends Fu{
        Zi(){
             //super(); 调用父类空参数构造方法
            System.out.println("Zi构造方法"+num);
        }
    }

     执行结果:

           Fu构造方法0

           Zi构造方法4

    通过结果发现,子类构造方法执行时中,调用了父类构造方法,这说明,子类构造方法中有一句super()。

      子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。

      当父类中没有空参数构造方法时,子类的构造方法必须有显示的super语句,指定要访问的父类有参数构造方法。

    注意:只要是构造方法默认第一行都是super();

         所有对象的父类Object

       static 修饰的类可以用类名直接调用

    super例子:

    描述学生和工人这两个类,将他们的共性name和age抽取出来存放在父类中,并提供相应的get和set方法,同时需要在创建学生和工人对象就必须明确姓名和年龄

    //定义Person类,将Student和Worker共性抽取出来
    class Person {
        private String name;
        private int age;
        public Person(String name, int age) {
            // super();
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
    class Student extends Person {
        // Student类的构造方法
        Student(String name, int age) {
            // 使用super关键字调用父类构造方法,进行相应的初始化动作
            super(name, age);
        }
        public void study() {// Studnet中特有的方法
            System.out.println(this.getName() + "同学在学习");
        }
    }
    class Worker extends Person {
        Worker(String name, int age) {
            // 使用super关键字调用父类构造方法,进行相应的初始化动作
            super(name, age);
        }
        public void work() {// Worker 中特有的方法
            System.out.println(this.getName() + "工人在工作");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Student stu = new Student("小明",23);
    stu.study();
            
    Worker w = new Worker("小李",45);
    w.work();
        }
    }
  • 相关阅读:
    【转】高并发情况下的单例模式
    json替换jsonp实现跨域请求
    asp.net学习——Response对象
    DoS攻击
    Java学习笔记-12.传递和返回对象
    Java学习笔记-11.运行期间类型鉴定
    Java学习笔记-10.io流
    java学习笔记-9.违例差错控制
    Java学习笔记-序
    java学习笔记-8.对象的容纳
  • 原文地址:https://www.cnblogs.com/lzw123-/p/9374209.html
Copyright © 2011-2022 走看看