今日内容
零、 复习昨日
一、作业
二、继承
三、重写
四、this和super
五、访问修饰符
零、 复习昨日
数组创建的两种方式
- new int[3];
- new int[]{值,值2,…}
- 存值: 数组名[下标] = 值
构造方法什么作用?有参无参构造什么区别?
- 创建对象
- 无参创建出的对象属性是默认值
- 有参创建出的对象属性是指定值
创建对象的过程:
- new 调用构造方法
- 先属性初始化,后再执行构造方法内代码
this是什么,什么作用?
- this指代当前类的对象
- this.属性; this.方法(); this();
- this(); 调用自己的无参构造
- this(参数); 调用自己有参构造
解释重载(Overload)
- 方法名一样,参数列表不一样
- 与返回值无关
类封装的步骤
- 属性私有private,提供set get方法
public class Square{int l;public Square(){this(1);}public Square(int l){this.l = l;} }
一、作业
3.创建类
创建老师类
创建学生类
老师带了很多学生
把学生存倒数组中 Student[] stus = new Student[3];
// 学生类
package com.qf.homework;/*** --- 天道酬勤 ---** @author QiuShiju* @date 2024/3/1* @desc*/
public class Student {private int age;private String name;public Student() {}public Student(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
// 老师类
package com.qf.homework;/*** --- 天道酬勤 ---** @author QiuShiju* @date 2024/3/1* @desc 老师类*/
public class Teacher {private int age;private String name;// 在老师类定义属性存储多个学生private Student[] stuArr;public Teacher() {}public Teacher(int age, String name) {this.age = age;this.name = name;}public Teacher(int age, String name, Student[] stuArr) {this.age = age;this.name = name;this.stuArr = stuArr;}public Student[] getStuArr() {return stuArr;}public void setStuArr(Student[] stuArr) {this.stuArr = stuArr;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
// 测试空指针异常
// 演示空指针public static void test() {// 创建老师Teacher teacher = new Teacher(40,"老王");/*** 这里会报空指针异常,即空对象错误* 是因为stuArr1数组本身 为空,因为老师对象中根本就没有数组*/// Student[] stuArr1 = teacher.getStuArr( );// stuArr1[0].getAge();// 创建数组赋值给老师的数组属性Student[] stuArr = new Student[3];teacher.setStuArr(stuArr);/*** 这里也会报空指针异常,即空对象错误* 这里数组确实存在了,但是数组中存储的是null* 即取出来stuArr2[0]这个null* null.getAge(),所以就报空指针*/Student[] stuArr2 = teacher.getStuArr( );stuArr2[0].getAge();}
// 测试给老师存储学生数组
public static void main(String[] args) {// 创建老师Teacher teacher = new Teacher(40,"老王");// 创建学生Student s1 = new Student(18, "小王");Student s2 = new Student(19, "小李");Student s3 = new Student(20, "小赵");// 创建数组,存学生Student[] stus = new Student[3];stus[0] = s1;stus[1] = s2;stus[2] = s3;// 将数组交给老师teacher.setStuArr(stus);// 从老师中取出学生,查看效果Student[] stuArr = teacher.getStuArr( );for (int i = 0; i < stuArr.length; i++) {String name = stuArr[i].getName( );int age = stuArr[i].getAge( );System.out.println("学生姓名:"+name+",学生年龄"+age );}}
二、继承[重点]
2.1 继承
生活中继承: 子继承父的财产
代码中继承: 子类继承父类,使用父类属性和方法
为什么需要继承:
- 减少代码重复
- 是形成多态的前提
语法:
public class A类 extends B类{} A类是子类,B类是父类
要求: java中类的继承只能是单继承!!! 类只能继承一个类!!!
// 演示: 父类Animal
package com.qf.oop;/*** --- 天道酬勤 ---** @author QiuShiju* @date 2024/3/1* @desc 父类Animal*/
public class Animal {int age;String name;void eat(){System.out.println("吃" );}
}
// 狗类Dog
package com.qf.oop;/*** --- 天道酬勤 ---** @author QiuShiju* @date 2024/3/1* @desc 狗类继承动物类* 狗类是子类* 动物类是父类*/
public class Dog extends Animal{// 继承
}
// 测试
public class TestExtends {public static void main(String[] args) {Dog dog = new Dog( );// Dog类继承Animal类,就可以父类属性和方法dog.name = "大黄";dog.eat();// Cat类继承Animal类,就可以父类属性和方法Cat cat = new Cat( );cat.age = 2;cat.eat();}
}
2.2 继承中属性
子类继承父类,就可以使用父类属性
如果给父类设置私有属性,子类就无法使用父类的属性
假如子类和父类中有重名的属性,子类默认使用自己
- ps: 一般情况下不会重复定义
2.3 继承中方法
继承中,子类可以使用父类非私有方法
继承中,子类 调用父类私有方法
子类中有与父类一样的方法,默认调用自己的
- 这就是重写!!! 很重要!!! (多态的前提)
- 跳转第三章详细了解重写…
2.4 继承中构造方法
在Animal类定义无参构造,里面有输出语句
在Dog类定义无参构造,里面有输出语句
在Test测试类中创建Dog对象,结果
Animal() Dog()
结论: 创建子类对象时**,先创建父类对象再创建子类对象**
这个结果其实是因为在每个类的每个构造方法内有个**
super()
**,一般super()默认是隐藏的,super是指代父类对象,super()是在调用父类无参构造,所以调用子类构造创建对象时先执行了父类构造创建了父类对象
详细的关于this和super的知识,看第四章
三、重写(Override)
重写,也可以叫做覆写,它是发生在继承中,子类重写父类方法,有要求
- 访问修饰符一致
- 返回值类型一致
- 方法名一致
- 参数列表一致
为什么需要重写?
- 原因1:父类的方法子类能用但是不好用不适合子类!重写后子类执行自己的方法
- 原因2:重写也是多态的前提
四、this和super
this | super | |
---|---|---|
是什么 | 指代当前类对象 | 父类对象 |
调用属性 | this.属性 (调用自己/父类属性) | super.属性(只能调用父类) |
调用方法 | this.方法(调用自己/父类方法) | super.方法(只能调用父类) |
构造方法 | this()/this(参数)只能调用自己构造方法 | super()/super(参数)调用父类构造方法 |
注意调用构造方法的语句,必须放在构造方法内,且放在第一行
package com.qf.oop;/*** --- 天道酬勤 ---** @author QiuShiju* @date 2024/3/1* @desc 狗类继承动物类* 狗类是子类* 动物类是父类*/
public class Dog extends Animal{// int age;String name = "二哈";// 无参构造public Dog(){System.out.println("Dog()" );}/*** 这是注解,告诉编译器此处是重写* 就得重写的规范*/@Overridevoid eat() {System.out.println("狗吃骨头" );}/*** 演示this和super*/public void show() {// 调用自己或父类属性nameSystem.out.println(this.name );// 只能调用父类属性nameSystem.out.println(super.name );this.eat();//调用自己/父类方法super.eat();//调用父类方法}
}
五、练习
pdf6
六、访问修饰符
访问修饰符,访问限定符,访问控制符,其实限制属性/方法能不能被访问到,即能不能被调用
当前类中 | 当前包其他类中 | 其他包子类 | 其他包非子类 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
缺省(默认) | √ | √ | × | × |
private | √ | × | × | × |
访问修饰符,访问限定符,访问控制符,其实限制属性/方法能不能被访问到,即能不能被调用