美文网首页
第六章:面向对象高级——继承的进一步研究。

第六章:面向对象高级——继承的进一步研究。

作者: 孤意的学习笔记 | 来源:发表于2017-10-18 11:53 被阅读0次

本章目标

  • 掌握子类对象的实例化过程
  • 掌握方法腹泻的概念及实现
  • 掌握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关键字的区别

相关文章

网友评论

      本文标题:第六章:面向对象高级——继承的进一步研究。

      本文链接:https://www.haomeiwen.com/subject/obysuxtx.html