本章目标
- 掌握子类对象的实例化过程
- 掌握方法腹泻的概念及实现
- 掌握super关键字的作用
1、具体内容
1.1、子类对象的实例化过程
class Person{ // 定义Person类
private String name ; // 定义name属性
private int age ; // 定义age属性
public Person(){
System.out.println("父类Person中的构造。") ;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age ;
}
public String getName(){
return this.name ;
}
public int getAge(){
return this.age ;
}
};
class Student extends Person{ // 定义Student类
private String school ; // 定义school属性
public Student(){
super() ; // 默认隐藏
System.out.println("子类Student中的构造。") ;
}
public void setSchool(String school){
this.school = school ;
}
public String getSchool(){
return this.school ;
}
};
public class InstanceDemo{
public static void main(String arsg[]){
Student stu = new Student() ;// 实例化子类对象
stu.setName("张三") ; // 此方法在Student类中没有明确定义
stu.setAge(30) ;
stu.setSchool("清华大学") ;
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge() + ",学校:" + stu.getSchool() ) ;
}
};
输出结果:
父类Person中的构造。
子类Student中的构造。
姓名:张三,年龄:30,学校:清华大学
从生活中,此道理也很好理解。父类:没有父亲肯定没有孩子。
实际上,此时,对于子类的构造方法中,隐含了一个“super”的语句,有时,也将父类称为超类。
1.2、方法的覆写
在Java中,访问权限一共分为四种,已经接触过三种:
- private:最小的访问权限
- default:什么都不声明
- public:最大的访问权限
大小关系:private<default<public
class Person{ // 定义父类
void print(){ // 默认的访问权限
System.out.println("Person --> void print()。") ;
}
};
class Student extends Person{ // 定义继承关系
public void print(){
System.out.println("Student --> void print()。") ;
}
};
public class OverrideDemo01{
public static void main(String args[]){
Student s = new Student() ;
s.print() ;
}
};
输出结果:
Student --> void print()。
以上代码是正确的操作,下面再来看一个不正确的操作。
class Person{ // 定义父类
public void print(){ // 默认的访问权限
System.out.println("Person --> void print()。") ;
}
};
class Student extends Person{ // 定义继承关系
void print(){ // 错误的,降低了访问权限
System.out.println("Student --> void print()。") ;
}
};
编译出错。
从之前的正确操作可以发现,如果现在子类将父类的方法覆写了,调用的时候肯定是调用被覆写过的方法,那么如果现在非要调用弗雷德方法该怎么办呢?
通过super关键字就可以完成功能,super关键字可以从子类访问父类中的内容。如果要访问被覆写过的方法:super.方法()。
class Person{ // 定义父类
void print(){ // 默认的访问权限
System.out.println("Person --> void print()。") ;
}
};
class Student extends Person{ // 定义继承关系
public void print(){
super.print() ; // 访问父类中被子类覆写过的方法
System.out.println("Student --> void print()。") ;
}
};
public class OverrideDemo03{
public static void main(String args[]){
Student s = new Student() ;
s.print() ;
}
};
输出结果:
Person --> void print()。
Student --> void print()。
如果要是用super,不一定非要在方法覆写之后使用,也可以明确的表示某个方法是从父类中继承而来的。使用super只是更加明确的说,要从父类中查找,就不从子类找了。
问题:如果现在在父类中使用private关键字声明了一个方法,那么在子类中使用default权限算是扩大权限吗?
class Person{ // 定义父类
private void print(){ // 默认的访问权限
System.out.println("Person --> void print()。") ;
}
public void fun(){ // 定义一个fun方法
this.print() ; // 调用print()方法
}
};
class Student extends Person{ // 定义继承关系
void print(){ // 覆写父类中的方法
// super.print() ; // 访问父类中被子类覆写过的方法
System.out.println("Student --> void print()。") ;
}
};
public class OverrideDemo04{
public static void main(String args[]){
Student s = new Student() ;
s.fun() ;
}
};
输出结果:
Person --> void print()
此时,方法并没有被覆写,而是相当于在子类中又重新定义了一个新的方发出来。
1.3、属性的覆盖
方法的覆写有很多的要求,属性的覆盖,主要就是指在子类中声明了与父类同名的属性。
class Person{ // 定义父类
public String info = "MLDN" ; // 定义一个公共属性
};
class Student extends Person{ // 定义继承关系
public String info = "LXH" ; // 定义了一个与父类中属性名称一致的属性
void print(){ // 覆写父类中的方法
System.out.println("父类中的属性:" + super.info) ;
System.out.println("子类中的属性:" + this.info) ;
}
};
public class OverrideDemo05{
public static void main(String args[]){
Student s = new Student() ;
s.print() ;
}
};
输出结果:
父类中的属性:MLDN
子类中的属性:LXH
但是,磁概念一般很少有人研究它,因为意义不大。
1.4、方法的覆写与重载的区别
1.5、super关键字
之前一直在见到super关键字的作用,super表示的是从子类调用父类中的制定操作:例如:调用属性、方法、构造等。因为在子类实例化时会默认调用父类中的无参构造,如果现在希望调用有参构造,则必须在子类中明确地声明。
class Person{ // 定义Person类
private String name ; // 定义name属性
private int age ; // 定义age属性
public Person(String name,int age){
this.setName(name) ;
this.setAge(age) ;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age ;
}
public String getName(){
return this.name ;
}
public int getAge(){
return this.age ;
}
public String getInfo(){
return "姓名:" + this.getName() + ";年龄:" + this.getAge() ;
}
};
class Student extends Person{ // 定义Student类
private String school ; // 定义school属性
public Student(String name,int age,String school){
super(name,age) ; // 明确调用父类中有两个参数的构造
this.school = school ;
}
public void setSchool(String school){
this.school = school ;
}
public String getSchool(){
return this.school ;
}
public String getInfo(){
return super.getInfo() + ";学校:" + this.getSchool() ;
}
};
public class SuperDemo01{
public static void main(String arsg[]){
Student stu = new Student("张三",30,"清华大学") ;// 实例化子类对象
System.out.println(stu.getInfo()) ;
}
};
输出结果:
姓名:张三;年龄:30;学校:清华大学
不管任何时候,子类实例化的时候,永远要先去调用父类中的构造方法,默认调用的是无参构造。
对于this和super,本身都可以调用构造方法,而且调用的时候都必须放在构造方法首行,所以这两个关键字肯定不能同时出现。
疑问,如果现在子类中所有的构造方法都是用了this()调用,那么这样一来是不是就不用调用父类的构造了?
class Person{ // 定义Person类
private String name ; // 定义name属性
private int age ; // 定义age属性
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
};
class Student extends Person{ // 定义Student类
private String school ; // 定义school属性
public Student(){
// this("LXH",30,"MLDN") ;
// 会在此处调用父类的构造,默认调用的是无参
}
public Student(String name,int age){
this() ;
}
public Student(String name,int age,String school){
this(name,age) ; // 明确调用父类中有两个参数的构造
this.school = school ;
}
};
public class SuperDemo02{
public static void main(String arsg[]){
Student stu = new Student("张三",30,"清华大学") ;// 实例化子类对象
System.out.println(stu.getInfo()) ;
}
};
2、总结
1、方法的覆写与重载的区别,以及覆写的实现,权限:private<default<public
2、子类对象的实例化过程:先调用父类的构造,在调用子类的构造
3、super与this关键字的区别
网友评论