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

原文地址:https://www.cnblogs.com/evilliu/p/7655262.html