Java中的类之间继承采用extends关键字实现
格式为:
访问控制符 [修饰符列表] class 类名 extends 父类名 {
定义属性
定义构造方法(super关键字)
定义方法
}
访问控制符使用public和不使用public
修饰符列表常用的有static,final等
1.父类的private属性子类无法访问,父类的protected属性子类可以访问
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
age = 0;
}
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;
}
public String say () {
return (this.name+" is saying sth");
}
}
class Student extends Person {
public Student(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
public Student(String name) {
super(name);
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getName()+" in "+xiaoming.getAge()+" states: "+xiaoming.say());
}
}
运行结果:
使用protected:
class Person {
private String name;
private int age;
protected Person(String name, int age) {
this.name = name;
this.age = age;
}
protected Person(String name) {
this.name = name;
age = 0;
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
}
class Student extends Person {
public Student(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
public Student(String name) {
super(name);
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getName()+" in "+xiaoming.getAge()+" states: "+xiaoming.say());
}
}
运行结果:
子类依然可以通过父类的protected方法访问到父类的private属性,依然正常
2.子类重写父类方法
子类重写父类的方法就是将父类中继承得到的方法的方法体进行修改,而方法的其余部分不变(返回值,参数列表,方法名...)
得到的新的方法就是重写的方法,同时有访问权限的限制,子类不能缩小方法的访问权限
public > default(不加修饰符) > protected > private
注意这里考虑private是没有意义的,因为子类本身就不能继承父类的private方法,即使定义一样的方法,也只能算子类自己新定义的方法,而不能算重写,所以只看前面的三个就可以了
public > default(不加修饰符) > protected
class Person {
private String name;
private int age;
protected Person(String name, int age) {
this.name = name;
this.age = age;
}
protected Person(String name) {
this.name = name;
age = 0;
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
}
class Student extends Person {
public Student(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
public Student(String name) {
super(name);
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return getName() + " said something";
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getName()+" in "+xiaoming.getAge()+" states: "+xiaoming.say());
}
}
输出结果:
上面的子类重写父类的方法,并将访问权限由protected修改为public,扩大了权限
重写是子类和父类之间构成的关系,在同一个类中仅有方法的重载
除了方法的重写,还可以重写变量,隐藏父类的变量,只有在调用父类相应的方法的时候,才会访问父类的变量
否则是访问的子类重写的变量
class Person {
private String name;
private int age;
String sex = "secret";
protected Person(String name, int age) {
this.name = name;
this.age = age;
}
protected Person(String name) {
this.name = name;
age = 0;
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
public String getOldSex() {
return sex;
}
}
class Student extends Person {
String sex = "male ";
public Student(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
public String getSex() {
return sex;
}
public Student(String name) {
super(name);
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return getName() + " said something";
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getOldSex()+" "+xiaoming.getSex());
}
}
输出结果:
调用父类的方法getOldSex()访问父类的sex属性-secret,调用子类的getSex()方法访问子类重写的sex属性-male
3.构造函数在继承中的处理
构造函数是比较特殊的,单独讨论:
class Person {
private String name;
private int age;
String sex = "secret";
protected Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Father constructor 1th");
}
protected Person(String name) {
this.name = name;
age = 0;
System.out.println("Father constructor 2th");
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
public String getOldSex() {
return sex;
}
}
class Student extends Person {
String sex = "male ";
public Student(String name, int age) {
super(name, age);
System.out.println("child constructor 2th");
// TODO Auto-generated constructor stub
}
public String getSex() {
return sex;
}
public Student(String name) {
super(name);
System.out.println("child constructor 1th");
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return getName() + " said something";
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getOldSex()+" "+xiaoming.getSex());
}
}
输出结果:
可以看到,先调用父类的构造函数,然后调用子类自己的构造函数
在实例化的时候,需要先将父类的属性初始化,如果没有显式地调用super()关键字
要么报错,要么因为没有需要初始化的属性而不报错,此时则是隐含了一个super关键字
用来对父类中的属性进行初始化
4.两个关键字this和super
this和super关键字的作用基本相同
唯一不同的是作用域,this调用本类中的属性和构造方法,或者用来带指当前的对象
super调用父类中的属性和方法(含构造方法)
1.this的使用
class Person {
private String name;
private int age;
String sex = "secret";
protected Person(String name, int age) {
this(name);
this.age = age;
System.out.println("Father constructor 1th");
}
protected Person(String name) {
this.name = name;
System.out.println("Father constructor 2th");
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
public String getOldSex() {
return sex;
}
}
class Student extends Person {
String sex = "male ";
public Student(String name, int age) {
super(name, age);
System.out.println("child constructor 2th");
// TODO Auto-generated constructor stub
}
public String getSex() {
return sex;
}
public Student(String name) {
super(name);
System.out.println("child constructor 1th");
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return getName() + " said something";
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
xiaoming.say();
System.out.print(xiaoming.getOldSex()+" "+xiaoming.getSex());
}
}
上面使用this(name)实现对本类构造方法的调用,使用this.age = age这样的形式解决二义性
this用法小结:
使用this代表类本身的构造别名,通过参数来区分在调用哪一个构造函数
可以实现构造函数之间的相互调用
例如有一个class A构造函数A () {}
A (int i) {this.i = i;}
A (int i, int j) {this.i = i; this.j = j;}
那么第三个构造函数可以简化为:
A (int j) {this(int i); this.j = j;}
注意在使用构造函数调用的时候,this语句必须写在第一行
如果使用return this;
之类的写法,就是在使用this指代当前对象的用法,返回这个对象本身
例子:
class Person {
private String name;
private int age;
String sex = "secret";
protected Person(String name, int age) {
this(name);
this.age = age;
System.out.println("Father constructor 1th");
}
protected Person(String name) {
this.name = name;
System.out.println("Father constructor 2th");
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
public String getOldSex() {
return sex;
}
public Person getCurrentObj () {
return this;
}
}
class Student extends Person {
String sex = "male ";
public Student(String name, int age) {
super(name, age);
System.out.println("child constructor 2th");
// TODO Auto-generated constructor stub
}
public String getSex() {
return sex;
}
public Student(String name) {
super(name);
System.out.println("child constructor 1th");
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return this.getName() + " said something";
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
System.out.println(xiaoming.getCurrentObj().say());
}
}
super关键字的用法1:
调用父类的方法:
1.构造方法
2.普通方法
class Person {
private String name;
private int age;
String sex = "secret";
protected Person(String name, int age) {
this(name);
this.age = age;
System.out.println("Father constructor 1th");
}
protected Person(String name) {
this.name = name;
System.out.println("Father constructor 2th");
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
protected String say () {
return (this.name+" is saying sth");
}
public String getOldSex() {
return sex;
}
public Person getCurrentObj () {
return this;
}
}
class Student extends Person {
String sex = "male ";
public Student(String name, int age) {
super(name, age);
System.out.println("child constructor 2th");
// TODO Auto-generated constructor stub
}
public String getSex() {
return sex;
}
public Student(String name) {
super(name);
System.out.println("child constructor 1th");
}
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String say() {
return "super.say() = "+super.say()+"\n"+this.getName() + " said something"+"\n"+"super.sex = "+super.sex;
}
}
public class T2 {
public static void main(String [] args) {
Student xiaoming = new Student("xiaoming", 21);
System.out.println(xiaoming.getCurrentObj().say());
}
}
上面的实例代码中的super(name, age) 是调用了父类的构造方法
下面的super.say()是调用父类的普通的方法
此外,super关键字还可以用来调父类中的被子类重写关键字
例如上面的代码中使用super.sex访问了父类中的sex属性
super和this的注意:
1.super不能和this同时放在首行(调用构造函数的时候),所以super和this关键字不能同时使用
2.不是在调用构造函数的时候,没有放在第一行的限制,所以可以同时使用