zoukankan      html  css  js  c++  java
  • java继承

    先看如下代码:

     1 package com.company;
     2 
     3 public class init_java {
     4     public static  void  main(String[] args){
     5         Employee man=new Manager("tom",22,23000,20000);
     6         Manager man1=new Manager("tom",22,23000,20000);
     7         System.out.println(man.getSalary());
     8 //        System.out.println(man.giveMon());
     9         System.out.println(man1.giveMon());
    10     }
    11 
    12 
    13 }
    14 
    15 
    16 class Employee{
    17     private int  age;
    18     private String name;
    19     private  double salary;
    20     private String alaname;
    21     public Employee(String aname,int aage,double asalary){
    22         this("evil");
    23         this.age=aage;
    24         this.salary=asalary;
    25         this.name=aname;
    26     }
    27     public Employee(String aname){
    28         this.alaname=aname;
    29     }
    30     public String getName(){
    31         System.out.println(this.name);
    32         return this.name;
    33     }
    34     public double getSalary(){
    35         return this.salary;
    36     };
    37     public String getAlaname(){
    38         return this.alaname;
    39     }
    40 }
    41 
    42 
    43 class Manager extends Employee{
    44     private double mon;
    45     public Manager(String aname,int aage,double asalary,double mon){
    46         super(aname,aage,asalary);
    47         this.mon=mon;
    48     }
    49     public double giveMon(){
    50         double salary= super.getSalary();
    51         salary+=this.mon;
    52         return salary;
    53     }
    54 }

     结果输出:

    继承:

    语法:   class  A extends  B{}   A继承B。java中只能单继承,和python不一样,python可以多继承。

    java的多态:

    A继承B,B属于超类、父类 A是子类和孩子类,关系是一对一对说,比如说超类和子类而不是超类和孩子类。

    子类A的对象类型是超类B的类型一样,也就是说子类A的对象类型既是超类B的类型也A类型,也就是说子类A的对象继承超类的B的方法和属性。

    但是超类B的对象却不是子类B的类型,也就是说超类B的对象不能调用子类A的方法。

    他们之间关系是"is a",就是说A是B的对象。

    构造器执行顺序:

        如果子类A没有显示执行超类B的构造器的话,会自动执行超类B的没有带参数的构造器,如果超类B没有不带参数的构造器话,执行的时候会报错。

     1 package com.company;
     2 
     3 public class init_java {
     4     public static  void  main(String[] args){
     5 //        Employee man=new Manager("tom",22,23000,20000);
     6         Manager man1=new Manager(20000);
     7 //        System.out.println(man.getSalary());
     8 //        System.out.println(man.giveMon());
     9         System.out.println(man1.giveMon());
    10     }
    11 
    12 
    13 }
    14 
    15 class Manager extends Employee{
    16     private double mon;
    17     public Manager(double mon){
    18 //        super(aname,aage,asalary);
    19         this.mon=mon;
    20     }
    21     public double giveMon(){
    22         double salary= super.getSalary();
    23         salary+=this.mon;
    24         return salary;
    25     }
    26 }
    27 
    28 class Employee{
    29     private int  age;
    30     private String name;
    31     private  double salary;
    32     private String alaname;
    33     public Employee(String aname,int aage,double asalary){
    34         this("evil");
    35         this.age=aage;
    36         this.salary=asalary;
    37         this.name=aname;
    38     }
    39     public Employee(String aname){
    40         this.alaname=aname;
    41     }
    42     public String getName(){
    43         System.out.println(this.name);
    44         return this.name;
    45     }
    46     public double getSalary(){
    47         return this.salary;
    48     };
    49     public String getAlaname(){
    50         return this.alaname;
    51     }
    52 }

     直接抛出来,没有找到合适的构造器。

    我们修改超类的构造器,变成无参数的构造器。或者去掉构造器。

     1 package com.company;
     2 
     3 public class init_java {
     4     public static  void  main(String[] args){
     5 //        Employee man=new Manager("tom",22,23000,20000);
     6         Manager man1=new Manager(20000);
     7 //        System.out.println(man.getSalary());
     8 //        System.out.println(man.giveMon());
     9 //        System.out.println(man1.giveMon());
    10     }
    11 
    12 
    13 }
    14 
    15 class Manager extends Employee{
    16     private double mon;
    17     public Manager(double mon){
    18 //        super(aname,aage,asalary);
    19         this.mon=mon;
    20     }
    21 //    public double giveMon(){
    22 //        double salary= super.getSalary();
    23 //        salary+=this.mon;
    24 //        return salary;
    25 //    }
    26 }
    27 
    28 class Employee{
    29 //    private int  age=22;
    30 //    private String name="tom";
    31 //    private  double salary=20000;
    32 //    private String alaname="evil";
    33     public Employee(){
    34         System.out.println("ok");
    35     }
    36 //    public Employee(String aname){
    37 //        this.alaname=aname;
    38 //    }
    39 //    public String getName(){
    40 //        System.out.println(this.name);
    41 //        return this.name;
    42 //    }
    43 //    public double getSalary(){
    44 //        return this.salary;
    45 //    };
    46 //    public String getAlaname(){
    47 //        return this.alaname;
    48 //    }
    49 
    50 }

     输出结果:

    显示调用:super(参数1,参数2.......)表示调用超类中的相应的参数类型的构造器。这句必须放在子类的构造器的第一句,才能生效!!

    同里想调用超类的方法用super.method形式!

    子类覆盖父类的方法:

    方法的签名:

    方法的名字和方法的参数列表叫做方法的签名。子类将相同的方法签名将覆盖超类的相应的方法。但是为了保持数据类型的兼容性,需要声明返回类型为子类的类型。

     注意:

          如上Manager 继承了Employee,Manager 对象也是Employee对象,如果将Manager 对象声明为employee对象的时候,Manager 对象无法调用自己的方法。

     1 package com.company;
     2 
     3 public class init_java {
     4     public static  void  main(String[] args){
     5         Employee man=new Manager("tom",20000,22,"evil",3000);
     6         double mon=man.giveMon();
     7         System.out.println(mon);
     8     }
     9 
    10 
    11 }
    12 
    13 class Manager extends Employee{
    14     private double mon;
    15     public Manager(String aname,double asalary,int age,String alaname,double mon){
    16         super(aname,asalary,age,alaname);
    17         this.mon=mon;
    18     }
    19     public double giveMon(){
    20         double salary=super.getSalary();
    21         salary+=this.mon;
    22         return salary;
    23     }
    24 }
    25 
    26 class Employee{
    27     private int  age=22;
    28     private String name="tom";
    29     private  double salary=20000;
    30     private String alaname="evil";
    31     public Employee(String aname,double asalary,int age,String alaname){
    32         this.age=age;
    33         this.name=aname;
    34         this.salary=asalary;
    35         this.alaname=alaname;
    36     }
    37     public Employee(String aname){
    38         this.alaname=aname;
    39     }
    40     public String getName(){
    41         System.out.println(this.name);
    42         return this.name;
    43     }
    44     public double getSalary(){
    45         return this.salary;
    46     };
    47     public String getAlaname(){
    48         return this.alaname;
    49     }
    50 
    51 }

     直接抛出错误:

    虽然你使用的Manager的构造器构造对象,但是你声明的对象的为employee类型,而不是Manager类型。所以在执行方法,jvm会找employee的方法表,找giveMon方法。显然没有。

    所以改成Manager类型就可以执行。

    多态属性:

    如上面代码的Manager man=new Manager("tom",20000,22,"evil",3000);中的man对象变量,虽然声明为Manger类型对象,但是我们的在调用的方法的时候,不仅可以调用他本身类Manager的方法,也可以调用超类的方法,而无需声明

    对象变量man为超类的类型。这种形式叫做多态属性,通过继承,子类对象在调用方法的时候,会根据自身的方法表和超类的方法表,由调用方法的签名(名字和参数列表),通过自身和超类的方法表来动态确认自己的调用的方法。

    我们叫做动态绑定

     子类在调用方法的执行过程如下:

    执行方法x.f(param)的时候,分以下步骤执行:

    1、编译器查看对象的声明类型和对象。

    2、编译器查看调用方法的参数类型。

    3、如果是被private、static、final方法或者构造器,编译器可以准确知道调用的是哪个方法。

    4、当执行方法的时候,并且采用动态绑定方法的时候,会根据方法的实际类型,所对应的合适的方法。从子类到超类一次查找。

    查找的过程需要查看多个类,java是怎么解决这个开销呢?在实际中,每个类中对有本类型的方法表(method table),每次查找的时候,通过查找方法表,来提高效率和减少开销。

     多态:

    1、无论是接口、普通类、抽象类都是声明父类的类型 调用子类的方法,来实现多态!!

  • 相关阅读:
    数据结构开发(23):二叉树中结点的查找、插入、删除与清除操作
    数据结构开发(22):二叉树的转换、深层特性与存储结构设计
    数据结构开发(21):树中属性操作与层次遍历
    数据结构开发(20):树中结点的查找、插入、清除与删除操作
    数据结构开发(19):树的定义、操作、存储结构与实现
    数据结构开发(18):归并排序和快速排序
    数据结构开发(17):冒泡排序和希尔排序
    HTTP协议的内容协商
    长轮询实现消息推送
    XHR的应用场景
  • 原文地址:https://www.cnblogs.com/evilliu/p/7655262.html
Copyright © 2011-2022 走看看