1 构造方法
- 概念:在创建对象的时候,用来给对象中的属性进行初始化
- 别名:构造函数 构造器
- 定义构造方法的格式:
修饰符 方法名称(形参){
方法体;
}
- 注意事项:
(1)构造方法在创建对象的时候,由虚拟机默认调用
(2)每创建一个对象,都会执行一次构造方法
(3)构造方法不能通过对象主动调用,只能在创建对象时自动调用
(4)如果在类中没有定义任何构造方法,系统默认提供一个没有参数的空参构造
(5)如果在类中定义过构造方法,系统不再提供任何构造
(6)在类中既要定义有参构造,也要定义空参构造(利用重载)
如果想在创建对象时给属性赋值,就可以使用有参构造
如果在创建对象时不需要给属性赋值,可以使用空参构造
(7)构造方法的名字必须和类名一模一样
(8)构造方法没有返回值类型
代码
package demo01;
public class Person {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
//定义一个有参构造方法
public Person(String name,int age){
this.name = name;
this.age = age;
}
//定义一个空参构造方法
public Person(){
}
public void eat(){
System.out.println("吃饭");
}
}
2 静态
- 不使用静态:
如果一个类型的多个对象中某一个属性值都相同,需要分别在对象中为这个相同的值分 配内存。如果需要将这个相同的属性值统一进行修改,每一个对象都要修改一次。
缺点:浪费内存空间 数据维护比较麻烦 - 使用静态:
多个对象中某一个属性值如果都相同,可以将该属性定义为静态修饰,修饰之后,将来 就不需要为每一个对象都分配一段空间来存储该属性,后续想要修改该属性的值,只需 要修改一次即可。
好处:节约内存 数据维护容易
2.1 静态变量的特点
- 静态变量使用关键字:static修饰
- 静态变量随着类型的加载,就存在
- 静态变量在创建对象之前就存在,可以在创建对象之前就使用
- 类型中定义的静态变量,可以被该类所有对象共享
- 静态变量可以使用对象调用,可以使用类名调用
- 当一个类型中每一个对象中的属性值都相同时,可以使用静态修饰该属性
2.2 静态方法的特点
- 某一个方法使用static修饰,该方法就变为一个静态方法
- 类型加载之后,可以使用静态方法
- 既可以使用对象调用,也可以使用类型调用
- 注意事项:
(1)静态方法不能访问非静态变量;静态方法在类型加载之后就已经可以访问,这时对象可能还没创建,对象没创建,非静态变量就没有存在,所以不能访问
(2)静态方法中不能调用非静态方法;非静态方法可以访问非静态变量,如果静态方法可以访问非静态方法,表示可以间接的访问非静态变量,和第一点矛盾,所以不能访问。
(3)静态方法中不能存在this关键字;this关键字指向对象,静态方法可以访问时,对象可能还没创建,所以无法指向对象
2.3 静态变量和非静态变量的区别
- 相同点:都属于成员变量
- 不同点:
(1)存储的空间不同:
静态变量在方法区中存储
非静态变量在堆内存中存储
(2)生命周期不同:
非静态变量随着对象的创建存在,随着对象回收消失
静态变量随着类的加载存在,随着加载类的回收消失
(3)调用方式不同:
静态变量可以使用对象调用,也可以使用类名调用
非静态变量只能使用对象调用
3 继承
- 概念:两个类之间实现子类和父类的关系
- 实现继承的关键字:extends
- 子类:用于继承的类型 派生类
- 父类:被其他类所继承 超类 基类
- 使用继承的好处:
(1)降低代码的冗余量
(2)提高代码的复用性 - 使用继承的缺点:
提高了代码的耦合性
3.1 继承的注意事项
- 父类中定义的私有方法,子类是不能继承的
- 父类中定义的私有属性,子类可以继承,但是不能直接访问
可以使用从父类中继承而来的公共方法区访问 - 父类中的构造方法,子类不能继承
原因1:
如果子类继承了父类的构造方法,那么这个构造方法的名字也无法和子类的类名保 持一致,和定义构造的方式冲突。
原因2:
父类的构造方法是用于给父类中的属性初始化,如果子类继承了父类的构造方法, 而且子类中有一个自己特殊的属性,那么从父类中继承的构造方法不能给自己的属 性初始化,所以子类应该定义自己的构造方法。
总结:
子类需要定义自己的构造方法
问题:在给属性赋值的时候,父类中继承的私有属性子类无法直接访问,无法赋值
解决:从父类中继承的私有属性,通过调用父类的有参构造间接赋值 - 子类和父类的继承,不能随意继承,需要遵循两个原则:
程序员类:姓名 工号 敲代码
项目经理类:姓名 工号 工资 敲代码 管理
往上抽取一个员工类当做父类:姓名 工号 敲代码
原则1:子类必须是父类的一种
原则2:父类中定义的属性和行为,是子类中的共同的内容
3.2 子父类继承中成员变量的关系
- 子类既可以访问本类的属性,也可以访问父类的属性
- 父类只能访问本类的属性,不能反过来访问子类的属性
- 在子类中访问变量:就近原则
如果使用子类的对象访问某一个变量,先去当前调用的方法中寻找有没有该变量的定 义,如果有就使用,如果没有就去当前对象中寻找有没有该变量的定义,如果有就使用, 如果没有,再去父类中寻找有没有该变量的定义,如果有就使用如果没有就编译报错。 - 如果子类的某一个方法中有一个形参,形参的名字和子类及父类中定义的名字一样
(1)想要访问形参:不加任何修饰符,根据就近原则即可访问
(2)想要访问子类中的属性:this修饰
(3)想要访问父类中的属性:super修饰
3.3 子父类继承中构造方法的关系
- 特点
(1)在子类的构造方法中,没有任何构造方法,系统会默认在子类构造构造方法的第 一行提供一个super();
(2)在子类的构造方法中,调用了父类的构造方法,系统不会再提供任何构造
(3)在子类的构造方法中,调用了子类的构造方法,系统也不再提供其他任何构造 - 通过以上的特点,总结:
创建一个子类对象之后,都会先默认或者直接调用父类的构造方法
目的:在初始化子类的数据之前,先初始化父类的数据
原因:在子类的构造方法中可能要使用父类的数据,如果不先初始化父类的数据,子类 就不能访问。 - 注意事项:
(1)如果在子类的构造方法中调用了父类构造,或者子类构造,必须在第一行调用
(2)在子类的构造中需要调用父类或者子类的构造,只能调用其中一个,只能调用一 次
(3)构造方法不能一直自己调用自己
3.4 父类继承中成员方法的关系
- 子类对象既可以访问父类的方法(私有方法除外),也可以访问本类的方法
- 父类对象只能访问本类的方法,不能反过来访问子类的方法
- 如果父类中定义了一个方法,子类也需要这个方法,但是不想使用父类方法中定义的内 容,子类可以对该方法进行重写。
- 重写特点:
(1)子类重写的方法,也是从父类继承而来的
(2)在子父类中,两个方法的方法名相同,参数列表相同,返回值类型相同,实现内 容可以不同。
(3)想要验证子类中的方法,是否是重写,可以使用一个注解
@Override
在方法上如果使用该注解,编译没问题,表示该方法是重写的
在方法中使用该注解,编译报错,表示该方法不是重写的,子类单独定义的 - 注意事项:
父类中定义的私有方法,子类不能重写,因为不能继承 - 补充:
(1)父类中定义的静态方法,子类可以继承的
(2)父类中定义的静态方法,子类不能重写的
(3)如果在子类中定义了一个和父类一模一样的静态方法,那么从父类继承的静态方 法会默认隐藏,只能使用子类单独定义的。