继承

作者: 须臾之北 | 来源:发表于2018-07-18 22:39 被阅读0次

继承

1. super关键字的学习

  • 逻辑关系:

    • Manager继承Employee成为Employee的一个子类
    • Manager的实例域增加了bonus属性
    • Manager类中相应增加了setBonus()方法
  • super关键字

    • 在计算Manager的salary时,我们需要家和奖金bonus,而父类的实例域均为private,由于,Manager类的构造器不可以访问Empoloyee类的私有域,所以,我们用super来实现子类对父类中构造器和方法的使用
  • Employee类

      import java.time.LocalDate;
          
      class Employee{
          
          //data field
          private String name;
          private double salary;
          private LocalDate hireDay;
          
          //constructor
          public Employee(String name,double salary,int year,int month,int day){
              this.name = name;
              this.salary = salary;
              this.hireDay = LocalDate.of(year,month,day);
          }
          
          //method
          public String getName(){
              return name;    
          }
          
          public double getSalary(){
              return salary;  
          }
          
          public LocalDate gethireDay(){
              return hireDay;
          }
          
          public void raiseSalary(double byPercent){
              salary += salary * byPercent/100;
          }
      }
    
  • Manager类

      class Manager extends Employee{
          private double bonus;
          
          public void setBonus(double bonus){
              this.bonus = bonus;
          }
          
          public Manager(String name,double salary,int year,int month,int day){
              super(name,salary,year,month,day);
              bonus = 0;  
          }
          
          public double getSalary(){
              return bonus + super.getSalary();
          }
      }
    
  • super.getSalary();

    • 调用父类的getSalary()方法
  • super(name,salary,year,month,day);

    • 调用父类的Employee(String name,double salary,int year,int month,int day)构造器
  • ManagerTest类

      public class Test{
          public static void main(String[] args){
              Manager boss = new Manager("hahaha",200,2018,7,16);
              boss.setBonus(50);
              
              Employee[] staff = new Employee[3];
              staff[0] = boss;
              staff[1] = new Employee("xixixi",100,2018,7,16);
              staff[2] = new Employee("xixixi",100,2018,7,16);
              
              //输出所有的Employee信息
              for(Employee e : staff){
                  System.out.println("name : " + e.getName() + ",salary : " + e.getSalary()); 
              }
          }   
      }
      /*
          在JDK1.8中输出结果为:
          ------------------------------
          name : hahaha,salary : 250.0
          name : xixixi,salary : 100.0
          name : xixixi,salary : 100.0
          ------------------------------
      */
    
  • super与this的区别

    • this的两个用途

      • 一是引用隐士参数
        • this.name = name;
      • 二是调用该类其他的构造器
        • this(name,salary)
    • super的两个用途

      • 一是调用超类的方法
        • super.getSalary()
      • 二是调用超类的构造器
        • super(name,salary,year,month,day);

2. 多态与动态绑定

  • 输出所有的Employee信息

      for(Employee e : staff){
          System.out.println("name : " + e.getName() + ",salary : " + e.getSalary()); 
      }
    
  • 当e引用Employee对象时,e.getSalary()调用的是Employee类中的getSalary()方法,当e引用Manager对象时,e.getSalary()调用的是Manager类中的getSalary()方法。

  • 一个对象变量可以指示多种实际类型的现象被称为多态,在运行时能够自动地选择调用哪个方法的现象称为动态绑定。

    • 可理解为:多态就是父类的引用指向子类对象。此时,对象变量是多态的。
  • 多态类型

    • 方法的多态
      • 方法的重载:
        • 方法名称相同,参数类型和个数不同,与返回值无关
      • 方法的重写(继承中使用)
        • 方法名称、参数类型、返回值与父类一致
    • 对象的多态
      • 父类的引用指向子类对象

3. 阻止继承:final类和方法

  • 回顾:

    • 实例域声明为final时,构造对象之后就不允许改变他们的值
  • 当类声明为final时,则不允许继承扩展

    • final类中的所有方法自动成为final方法
  • 当方法声明为final时,子类将不能覆盖这个方法。

  • 强制类型转换

    • Manager为Employee一个子类,此时:
      • Employee boss = new Manager();

      • 若要调用Manager类中特定方法setBonus(),则需要强制类型转换

          if(boss instanceof Manager){
              Manager bos = (Manager)boss;
              bos.setBouns(500);       
          }
        
      • 向下转型的强制类型转换不太常见。

4. 访问控制符号

  • private
    • 仅对本类可见
  • protected
    • 对本包和所有子类可见
  • public
    • 对所有类可见

抽象类

1. 抽象类相关概念

  • 包含一个或者多个抽象方法的类本身被声明为抽象的

  • 除抽象方法外,抽象类还可以包含具体的数据和具体方法

  • 类即使不含有抽象方法,也可以将类声明为抽象类

  • 抽象类不能被实例化

  • 可以定义一个抽象类的对象引用,指向引用一个非抽象子类的实例化对象

      Person p = new Student(); 
    

2. 抽象类的使用举例

  • 定义抽象类Person
    • 抽象方法getDescription();
    • 具体方法:getName();
        public abstract class Person{
            private String name;
            public abstract String getDescription();
            
            public Person(String name){
                this.name = name;
            }
            
            public String getName(){
                return name;
            }
        }
  • 定义抽象类子类Employee类

      import java.time.LocalDate;
    
      class Employee extends Person{
          private double salary;
          private LocalDate hireDay;
          
          public Employee(String name,double salary,int year,int month,int day){
                  super(name);
                  this.salary = salary;
                  hireDay = LocalDate.of(year,month,day);
          }
          
          public String getDescription(){
              return String.format("an employee with a salary of $.2f",salary);   
          } 
          
          public double getSalary(){
              return salary;
          }
          
          public LocalDate gethireDay(){
              return hireDay; 
          }
          
          public void raiseSalary(double byPercent){
              salary += salary * byPercent/100;
          }
      }
    
  • 定义抽象类的子类Student类

      class Student extends Person{
          private String major;
          
          public Student(String name,String major){
              super(name);
              this.major = major;
          }
          
          public String getDescription(){
              return "a student majoring in" + major;
          }
      }
    
  • Person类测试

      public class PersonTest{
          public static void main(String[] args){
              Person[] people = new Person[2];    
              
              people[0] = new Employee("hahaha",200,2018,7,17);
              people[1] = new Student("xixixi","CS");
              
              for(Person p : people){
                  System.out.println(p.getName() + " , " + p.getDescription());
              }       
          }   
      }
    
      /*
          1. 此时涉及到对象的多态:父类的引用指向子类对象
          2. 父类类型数组中存放着子类的实例化对象
          3. 虽然Person为抽象类,但是
              Persoon[] people = new Person[3];仍然正确
      */
    

Object类

  • 所有类的超类
    • equals()方法

      • Object中的equals用于检测一个对象是否等于另外一个对象。
      • Object中是判断两个对象是否为同一引用
      • 我们需要重写equals()方法
    • Employee中重写equals方法

        public class Employee{
            ......
                
            public boolean equals(Object otherObject){
                //判断使用为同一引用
                if(otherObject == this)
                    return true;
                
                //判断otherObject是否为空
                if(otherObject == null)
                    return false;
                
                //判断是否属于同一类
                if(getClass() != otherObject.getClass())
                    return false;
                
                //现在可知Employee为otherObject的一个实例化对象
                Employee other = Employee(otherObject);
            
                //判断是否相等
                return this.name == other.name && this.salary = other.salary && this.hireDay == other.hireDay;
            }
      
        }
      

泛型数组列表

优点

  • 动态的更改数组的大小
  • 可存放任意类型的数组

例子

  • 声明和构造一个保存Employee对象的数组列表

    ArrayList<Employee> staff = new ArrayList<>();
    <>中为Employee

  • 为数组列表中添加Employee对象

    staff.add(new Employee("hahah",200,2018,7,16));

  • 返回当前数组中的元素个数

    staff.size();

缺点

  • 不太方便获取数组列表中的元素
  • 因此在遍历数组列表时,可以将数组列表转换为数组
    • 扩展数组,并添加所有元素

      ArrayList <X> list = new ArrayList<>();
      while(....){
      x = ....;
      list.add(x);
      }

      X[] a = new X[list.size()];
      list.toArray(a);

相关文章

  • 继承 继承

    属性拷贝 继承不单单能通过原型链实现,也能通过其他方式实现,属性拷贝就是其中一种方法。 通过属性拷贝也能实现继承子...

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • 原型相关(二)

    1.继承 继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)ECMAScript只支持实现继承,并且主...

  • 继承

    继承的引入和概述 继承案例和继承的好处 继承的弊端 Java中继承的特点 继承的注意实现和什么时候使用继承 继承中...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • 7、面向对象的程序设计3(《JS高级》笔记)

    三、继承 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际方法。由...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

网友评论

      本文标题:继承

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