12-01构造方法
- 构造方法是构建创造时用的方法,即就是对象创建时要执行的方法
- 使用new关键字创建对象时,同时给成员变量赋值,给对象属性进行初始化。如:
Perons p = new Person(“张三”,23); 在new 的时候给p对象的name属性和age属性进行赋值,使这个对象的属性有值。 - 构造方法定义
构造方法的格式:
修饰符 构造方法名(参数列表)
{
} - 构造方法没有返回值类型。也不需要写返回值。因为它是为构建对象的,对象创建完,方法就执行结束。
- 构造方法名称必须和类型保持一致。构造方法没有具体的返回值。
- 每一class类都必须有一个构造方法,构造方法不写也有,编译的时候,javac,系统会自动检查类中是否有构造方法,如果没有编译器就会自动添加一个构造方法
例子
class Person {
// Person的成员属性age和name
private int age;
private String name;
// Person的构造方法,拥有参数列表
Person(int a, String nm) {
// 接受到创建对象时传递进来的值,将值赋给成员属性
age = a;
name = nm;
}
}
12-02构造方法的调用赋值
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();
}
}
12-03构造方法的内存
12-04构造方法的重载
- 一个类中可以有多个构造方法,多个构造方法是以重载的形式存在的
- 构造方法是可以被private修饰的,作用:其他程序无法创建该类的对象。
12-05构造方法和一般方法区别
- 格式不同
构造方法 : 修饰符 类名(参数类型 参数 …){
初始化成员变量
}
一般方法: 需要有返回值类型 - 作用不同
构造方法一般用来给成员变量初始化;
一般方法根据需求而定; - 调用方式不同
构造方法创建对象时调用, 或者this() super() 语句调用
普通方法需要对象调用或者静态方法直接调用静态方法. - 执行不同
构造方法在对象创建时就执行了,而且只执行一次。
一般方法是在对象创建后,需要使用时才被对象调用,并可以被多次调用
12-06 this在构造方法之间的调用
- 方法之间可以通过方法名进行调用,可是构造方法,无法通过构造方法名来相互调用。构造方法之间的调用,通过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;
}
}
12-07 this在构造方法之间的内存图
12-08 super关键字
-
在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句。
-
格式:
调用本类中的构造方法:this(实参列表);
调用父类中的空参数构造方法:super();
调用父类中的有参数构造方法:super(实参列表); -
子类构造方法执行时中,调用了父类构造方法,这说明,子类构造方法中有一句super()。
-
子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。
-
当父类中没有空参数构造方法时,子类的构造方法必须有显示的super语句,指定要访问的父类有参数构造方法。
-
子类父类的内存图
-
子类默认会调用父类的无参构造, 但如果父类没有无参构造,子类的构造方法继续调用父类的无参构造就会报错。
因此子类构造方法的第一行需要调用父类的构造方法,既可以调用父类的无参构造,也可以调用父类的有参构造,这样语法上就不会报错。 -
构造方法第一行,写this()还是super()
this() 是调用本类的构造方法,super()是调用父类的构造方法, 且两条语句不能同时存在,保证子类的所有构造方法调用到父类的构造方法即可 -
无论如何,子类的所有构造方法,直接或间接必须调用到父类构造方法;
-
子类的构造方法什么都不写,默认的构造方法第一行super()
12-09 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();
}
}
12-10 完整员工案例
public abstract class Employee {
private String id;// 员工编号
private String name; // 员工姓名
//空参数构造方法
public Employee() {
super();
}
//有参数构造方法
public Employee(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//工作方法(抽象方法)
public abstract void work();
}
public abstract class Developer extends Employee {
//空参数构造方法
public Developer() {
super();
}
//有参数构造方法
public Developer(String id, String name) {
super(id, name);
}
}
public abstract class Maintainer extends Employee {
//空参数构造方法
public Maintainer() {
super();
}
//有参数构造方法
public Maintainer(String id, String name) {
super(id, name);
}
}
public class JavaEE extends Developer {
//空参数构造方法
public JavaEE() {
super();
}
//有参数构造方法
public JavaEE(String id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在研发淘宝网站");
}
}
public class Android extends Developer {
//空参数构造方法
public Android() {
super();
}
//有参数构造方法
public Android(String id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在研发淘宝手机客户端软件");
}
}
public class Network extends Maintainer {
//空参数构造方法
public Network() {
super();
}
//有参数构造方法
public Network(String id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在检查网络是否畅通");
}
}
public class Hardware extends Maintainer {
//空参数构造方法
public Hardware() {
super();
}
//有参数构造方法
public Hardware(String id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在修复打印机");
}
}
public class Test {
public static void main(String[] args) {
//创建JavaEE工程师员工对象,该员工的编号000015,员工的姓名 小明
JavaEE ee = new JavaEE("000015", "小明");
//调用该员工的工作方法
ee.work();
}
}