一、构造方法的补充
构造方法到底要不要参数,要看对象的数据能不能写死
如果对象的数据都一样,意味着可以写死,就不需要传参。
如果对象的数据都不一样,意味着不能写死,那就需要传参
二、jvm内存管理
堆:new出来的对象(包括成员变量)
栈:局部变量(包括方法的参数)的地址
注意:基本类型变量中装的是具体的数,引用类型变量中装的是地址
三、引用型类型数组
1.基本类型引用数组
基本类型引用数组默认值为0
int[] arr =new int[3];
2.引用类型数组
给元素赋值时,需要new个对象
- 若想访问对象的数据,需要通过数组元素去打点来访问
给引用类型元素赋值需要new个对象
Student[] stus = new Student[3]; //创建Student数组对象
stus[0] = new Student("zhangsan", 25, "LF"); //创建Student对象
stus[1] = new Student("lisi", 24, "JMS");
stus[2] = new Student("wangwu", 26, "SD");
System.out.println(stus[0].name); //输出第1个学生的名字
stus[1].age = 27; //修改第2个学生的年龄为27
stus[2].sayHi(); //第3个学生跟大家问好
for (int i = 0; i < stus.length; i++) { //遍历所有学生
System.out.println(stus[i].name); //输出每个学生的名字
stus[i].sayHi(); //每个学生跟大家问好
}
引用类型数组内存图
引用类型数组的默认值为null
四、继承
继承的作用:代码复用
- 通过extends来实现继承
- 超类/父类:共有的属性和行为
派生类/子类:特有的属性和行为
- 派生类可以访问派生类的+超类的,但超类不能访问派生类的
- 一个超类可以有多个派生类,但一个派生类只能继承一个超类-----------单一继承
- 继承具有传递性
java规定:构造派生类之前必须先构造超类
在派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法
public class SuperDemo {
public static void main(String[] args) {
Boo o = new Boo();
}
}
class Aoo{
Aoo(){
System.out.println("超类构造方法");
}
}
class Boo extends Aoo{
Boo(){
super(); //默认的,调用超类的无参构造方法
System.out.println("派生类构造方法");
}
}
在派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供
> 注意:super()调用超类构造方法,必须位于派生类构造方法的第一行
class Coo{
Coo(int a){
}
}
class Doo extends Coo{
Doo(){
super(5); //调用Coo的有参构造方法
}
五、super
指代当前对象的超类对象
super的用法:
- super.成员变量名-------------------------访问超类的成员变量
- super.方法名()-----------------------------调用超类的方法
- super()---------------------------------------调用超类的构造方法
六、向上造型
超类型的引用指向派生类的对象
何时向上造型:
多种角色能干的事都一样的时候,可以将多种角色统一造型到超类数组中,实现代码复用
public class UploadDemo {
public static void main(String[] args) {
Aoo o1 = new Aoo();
o1.a = 1;
o1.show();
//o1.b = 2; //编译错误
//o1.test(); //编译错误,超类不能访问派生类的
Boo o2 = new Boo();
o2.b = 1;
o2.test();
o2.a = 2; //正确
o2.show(); //正确,派生类可以访问超类的
Aoo o3 = new Boo(); //向上造型
o3.a = 1;
o3.show();
//o3.b = 2; //编译错误
//o3.test(); //编译错误,能点出来什么,看引用的类型
}
}
class Aoo{
int a;
void show(){
}
}
class Boo extends Aoo{
int b;
void test(){
}
}
七、方法的重写(override/overriding):重新写、覆盖
发生在父子类中,方法名相同,参数列表相同
class 餐馆{
void 做餐(){ 做中餐 }
}
//1)我还是想做中餐-----------------不需要重写
class Aoo extends 餐馆{
}
//2)我想改做西餐-------------------需要重写
class Aoo extends 餐馆{
void 做餐(){ 做西餐 }
}
//3)我想在中餐基础之上加入西餐--------需要重写(先super中餐,再加入西餐)
class Aoo extends 餐馆{
void 做餐(){
super.做餐();
做西餐
}
}
八、需要注意的问题:
重写需遵循"两同两小一大"原则
两同:方法名相同;参数列表相同
两小:派生类方法的返回值类型小于或等于超类方法的
void和基本类型时,必须相等; 引用类型时,小于或等于
//超类大,派生类小---------爸爸大,儿子小
class Coo{
void show(){}
double test(){ return 0.0; }
Student say(){ return null; }
Person sayHi(){ return null; }
}
class Doo extends Coo{
//int show(){ return 1; } //编译错误,void时必须相等
//int test(){ return 0; } //编译错误,基本类型时必须相等
//Person say(){ return null; } //编译错误,引用类型时必须小于或等于
Student sayHi(){ return null; } //正确,Student小于Person
}
一大:派生类方法的访问权限大于或等于超类方法的