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、无论是接口、普通类、抽象类都是声明父类的类型 调用子类的方法,来实现多态!!

  • 相关阅读:
    【Elasticsearch 技术分享】—— ES 常用名词及结构
    【Elasticsearch 技术分享】—— Elasticsearch ?倒排索引?这都是什么?
    除了读写锁,JUC 下面还有个 StampedLock!还不过来了解一下么?
    小伙伴想写个 IDEA 插件么?这些 API 了解一下!
    部署Microsoft.ReportViewe
    关于TFS强制undo他人check out
    几段查看数据库表占用硬盘空间的tsql
    How to perform validation on sumbit only
    TFS 2012 Disable Multiple Check-out
    在Chrome Console中加载jQuery
  • 原文地址:https://www.cnblogs.com/evilliu/p/7655262.html
Copyright © 2011-2022 走看看