------ android培训、java培训、期待与您交流! ----------
一、super关键字
1、super关键字的作用
①调用父类的构造方法
②调用父类的成员方法
需要注意:super 只能应用在成员方法和构造方法中,不能应用在静态方法中(和this 是一样的),如果在构造方法中使用必须放在第一行。
2、为什么会有super关键字?
①因为子类必须要调用父类的构造方法,先把父类构造完成,因为子类依赖于父类,没有父,也就没有子;
②有时需要在子类中显示的调用父类的成员方法
那么产生了一个问题,我们以前为什么没有看到super,而且我们也有继承,如:Student继承了Person?
因为子类中我们没有显示的调用构造方法,那么他会默认调用父类的无参构造方法,此种情况下如果父类中没有无参构造方法,那么编译时将会失败
注意:构造方法不存在覆盖的概念,构造方法可以重载
3、用法一:调用默认构造方法
<span style="font-size:18px;color:#333333;">public class SuperTest01 {
public static void main(String[] args) {
Person student = new Student();
}
}
class Person {
// 学号
private int id;
// 姓名
private String name;
// 性别
private boolean sex;
// 地址
private String address;
// 年龄
private int age;
public Person() {
// System.out.println(this);
System.out.println("----------Person-----------");
}
// 设置学号
public void setId(int studentId) {
id = studentId;
}
// 读取学号
public int getId() {
return id;
}
public void setName(String studentName) {
name = studentName;
}
public String getName() {
return name;
}
public void setSex(boolean studentSex) {
sex = studentSex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String studentAddress) {
address = studentAddress;
}
public String getAddress() {
return address;
}
public void setAge(int studentAge) {
if (studentAge >= 0 && studentAge <= 120) {
age = studentAge;
}
}
public int getAge() {
return age;
}
}
class Student extends Person {
// 班级编号
private int classesId;
public Student() {
// System.out.println(this);
// 显示调用父类的构造方法
// 调用父类的无参的构造函数
// super();
System.out.println("--------Student----------");
// 编译错误,必须将super 放到构造函数的第一语句
// 必须先创建父类,才能创建子类
// super();
}
public void setClassesId(int classesId) {
this.classesId = classesId;
}
public int getClassesId() {
return classesId;
}
}</span>
关于构造方法的执行顺序,先执行父类的再执行子类的,必须完成父类的所有初始化,才能创建子类
4、用法二:调用带参数的构造方法
<span style="font-size:18px;color:#333333;">public class SuperTest02 {
public static void main(String[] args) {
/*
* Person person_student = new Student(); person_student.setId(1001);
* person_student.setName("张三"); person_student.setSex(true);
* person_student.setAddress("北京"); person_student.setAge(20);
*/
// 编译出错,因为Person 看不到子类Student 的属性
// person_student.setClassesId(10);
/*
* person_student.printInfo(); System.out.println(""); Person person_emp
* = new Employee(); person_emp.setId(1002); person_emp.setName("李四");
* person_emp.setSex(true); person_emp.setAddress("上海");
* person_emp.setAge(30);
*/
// 编译出错,因为Person 看不到子类Employee 的属性
// person_emp.setWorkYear(10);
// person_emp.printInfo();
Person person_student = new Student(1001, "张三", true, "北京", 20, 10);
person_student.printInfo();
}
}
class Person {
// 学号
private int id;
// 姓名
private String name;
// 性别
private boolean sex;
// 地址
private String address;
// 年龄
private int age;
public Person() {
System.out.println("--------------Person-------------");
}
public Person(int id, String name, boolean sex, String address, int age) {
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.age = age;
}
public void printInfo() {
System.out.println("id=" + id + ", name=" + name + ",sex=" + sex
+ ", address=" + address + ", age=" + age);
}
// 设置学号
public void setId(int studentId) {
id = studentId;
}
// 读取学号
public int getId() {
return id;
}
public void setName(String studentName) {
name = studentName;
}
public String getName() {
return name;
}
public void setSex(boolean studentSex) {
sex = studentSex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String studentAddress) {
address = studentAddress;
}
public String getAddress() {
return address;
}
public void setAge(int studentAge) {
if (studentAge >= 0 && studentAge <= 120) {
age = studentAge;
}
}
public int getAge() {
return age;
}
}
class Student extends Person {
// 班级编号
private int classesId;
public Student(int id, String name, boolean sex, String address, int age,
int classesId) {
/*
* this.id = id; this.name = name; this.sex = sex; this.address =
* address; this.age= age; this.classesId = id;
*/
/*
* setId(id); setName(name); setSex(sex); setAddress(address);
* setAge(age); this.classesId = classesId;
*/
// 手动调用调用带参数的构造函数
super(id, name, sex, address, age);
this.classesId = classesId;
}
public void setClassesId(int classesId) {
this.classesId = classesId;
}
public int getClassesId() {
return classesId;
}
public void printInfo() {
System.out.println("id=" + getId() + ", name=" + getName() + ",sex=" + getSex() + ",
address=" + getAddress() + ", age=" + getAge() + ",classesid=" + classesId);
}
}
class Employee extends Person {
// 工作年限
private int workYear;
public void setWorkYear(int workYear) {
this.workYear = workYear;
}
public int getWorkYear() {
return workYear;
}
public void printInfo() {
System.out.println("id=" + getId() + ", name=" + getName() + ",sex=" + getSex() + ",
address=" + getAddress() + ", age=" + getAge() + ", workYear=" + workYear);
}
}</span>
5、用法三:采用super调用父类的方法
<span style="font-size:18px;color:#333333;">public class SuperTest03 {
public static void main(String[] args) {
Person person_student = new Student();
person_student.setId(1001);
person_student.setName("张三");
person_student.setSex(true);
person_student.setAddress("北京");
person_student.setAge(20);
print(person_student);
Person person_emp = new Employee();
person_emp.setId(1002);
person_emp.setName("李四");
person_emp.setSex(true);
person_emp.setAddress("上海");
person_emp.setAge(30);
print(person_emp);
}
private static void print(Person person) {
person.printInfo();
}
}
class Person {
// 学号
private int id;
// 姓名
private String name;
// 性别
private boolean sex;
// 地址
private String address;
// 年龄
private int age;
public void printInfo() {
System.out.println("id=" + id + ", name=" + name + ",sex=" + sex
+ ", address=" + address + ", age=" + age);
}
// 设置学号
public void setId(int studentId) {
id = studentId;
}
// 读取学号
public int getId() {
return id;
}
public void setName(String studentName) {
name = studentName;
}
public String getName() {
return name;
}
public void setSex(boolean studentSex) {
sex = studentSex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String studentAddress) {
address = studentAddress;
}
public String getAddress() {
return address;
}
public void setAge(int studentAge) {
if (studentAge >= 0 && studentAge <= 120) {
age = studentAge;
}
}
public int getAge() {
return age;
}
}
class Student extends Person {
// 班级编号
private int classesId;
public void setClassesId(int classesId) {
this.classesId = classesId;
}
public int getClassesId() {
return classesId;
}
public void printInfo() {
//System.out.println("id=" + getId() + ", name=" + getName() + ",sex=" + getSex() + ",
address=" + getAddress() + ", age=" + getAge() + ",classesid=" + classesId);
//采用super 调用父类的方法
super.printInfo();
System.out.println("classesId=" + classesId);
}
}
class Employee extends Person {
// 工作年限
private int workYear;
public void setWorkYear(int workYear) {
this.workYear = workYear;
}
public int getWorkYear() {
return workYear;
}
public void printInfo() {
//System.out.println("id=" + getId() + ", name=" + getName() + ",sex=" + getSex() + ",
address=" + getAddress() + ", age=" + getAge() + ", workYear=" + workYear);
System.out.println("workYear=" + workYear);
//采用super 调用父类的方法
super.printInfo();
}
}</span>
二、final关键字
1、final特点
①final表示不可改变的含义
②采用final 修饰的类不能被继承
③采用final 修饰的方法不能被覆盖
④采用final 修饰的变量不能被修改
⑤final 修饰的变量必须显示初始化
⑥如果修饰的引用,那么这个引用只能指向一个对象,也就是说这个引用不能再次赋
值,但被指向的对象是可以修改的
⑦构造方法不能被final 修饰
⑧会影响JAVA 类的初始化:final 定义的静态常量调用时不会执行java 的类初始化方
法,也就是说不会执行static 代码块等相关语句,这是由java 虚拟机规定的。我们
不需要了解的很深,有个概念就可以了。
2、采用final修饰的类不能被继承
<span style="font-size:18px;color:#333333;">public class FinalTest01 {
public static void main(String[] args) {
}
}
final class A1 {
public void test1() {
}
}// 不能继承A1,因为A1 采用final 修饰了
class B1 extends A1 {
public void test2() {
}
}
</span>
3、采用final 修饰的方法不能被覆盖
<span style="font-size:18px;color:#333333;">public class FinalTest02 {
public static void main(String[] args) {
}
}
class A1 {
public final void test1() {
}
}
class B1 extends A1 {
// 覆盖父类的方法,改变其行为
// 因为父类的方法是final 修饰的,所以不能覆盖
public void test1() {
}
public void test2() {
}
}</span>
4、采用final 修饰的变量(基本类型)不能被修改
<span style="font-size:18px;color:#333333;">public class FinalTest03 {
private static final long CARD_NO = 878778878787878L;
public static void main(String[] args) {
// 不能进行修改,因为CARD_NO 采用final 修改了
CARD_NO = 99999999999999L;
}
}</span>
5、final 修饰的变量必须显示初始化
<span style="font-size:18px;color:#333333;">public class FinalTest04 {
// 如果是final 修饰的变量必须初始化
private static final long CARD_NO = 0L;
public static void main(String[] args) {
int i;
// 局部变量必须初始化
// 如果不使用可以不初始化
System.out.println(i);
}
}</span>
6、如果修饰的引用,那么这个引用只能指向一个对象,也就是说这个引用不能再次赋值,但被指向的对象是可以修改的
<span style="font-size:18px;color:#333333;">public class FinalTest05 {
public static void main(String[] args) {
Person p1 = new Person();
//可以赋值
p1.name = "张三";
System.out.println(p1.name);
final Person p2 = new Person();
p2.name = "李四";
System.out.println(p2.name);
//不能编译通过
//p2 采用final 修饰,主要限制了p2 指向堆区中的地址不能修改(也就是p2 只能指向一个对象)
//p2 指向的对象的属性是可以修改的
p2 = new Person();
}
}
class Person {
String name;
}</span>