• java中的多态关系的运用


    1、多态发生的三个必备条件

      继承、重写、父类引用指向子类对象

    2、注意

      当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

      方法的重写,也就是子类能够重写父类的方法

      当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字super。

    3、好处

      可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

    4、例子

     1 //父类
     2 package com.test.five;
     3 
     4 public class Parent {
     5     public void Test(){
     6         System.out.println("我 是 父类");
     7     }
     8 }
     9 
    10 //子类一
    11 package com.test.five;
    12 
    13 public class Child extends Parent {
    14     public void Test(){
    15         System.out.println("我 是大儿子");
    16     }
    17     public void Sex(){
    18         System.out.println("我 是个男的");
    19     }
    20 }
    21 //子类二
    22 package com.test.five;
    23 
    24 public class Sister extends Parent{
    25     public void Test(){
    26         System.out.println("我也是个子类");
    27     }
    28     public void Sex(){
    29         System.out.println("我是个女儿");
    30     }
    31 }
    32 //测试类
    33     package com.test.five;
    34 
    35 public class Test {
    36     public static void main(String[] args) {
    37         Parent p = new Child();
    38         p.Test();//父类声明,子类创建,调用该对象的方法(子类父同时所拥有的方法)
    39         Show(p);
    40         Show(new Sister());
    41         Show(new Child());
    42     }
    43     //测试类中的静态类方法,在测试类中可以直接调用此方法(不用再实例化类的对象)
    44     public static void Show(Parent p){
    45         p.Test();
    46         if( p instanceof Child){
    47             Child c = (Child)p;
    48             c.Sex();
    49         }else if(p instanceof Sister){
    50             Sister s = (Sister)p;
    51             s.Sex();
    52         }
    53     }
    54 }

    得出的结果是:

    我 是大儿子
    我 是大儿子
    我 是个男的
    我也是个子类
    我是个女儿
    我 是大儿子
    我 是个男的

     5、注意(例子)

     1 //父类
     2 package com.test.six;
     3 
     4 public class Emploee {
     5     private String name;
     6     private String address;
     7     private int num;
     8     public Emploee(String name,String address,int num){
     9         System.out.println("Emploee的构造函数");
    10         this.name = name;
    11         this.address = address;
    12         this.num = num;
    13     }
    14     public void check(){
    15         System.out.println("Emploee中check的name:"+this.name+" ,address =  "+this.address);
    16     }
    17     public String toString(){
    18         return name+"  "+address+"  "+num;
    19     }
    20     public String getName() {
    21         return name;
    22     }
    23     public void setName(String name) {
    24         this.name = name;
    25     }
    26     public String getAddress() {
    27         return address;
    28     }
    29     public void setAddress(String address) {
    30         this.address = address;
    31     }
    32     public int getNum() {
    33         return num;
    34     }
    35 }
    36 
    37 //子类
    38 package com.test.six;
    39 
    40 public class Salary extends Emploee {
    41     private double salary;
    42     //构造函数
    43     public Salary(String name, String address, int num,double salary) {
    44         super(name, address, num);
    45         System.out.println("salary的构造函数");
    46         setSalary(salary);
    47     }
    48     public double getSalary() {
    49         return salary;
    50     }
    51 
    52     public void setSalary(double salary) {
    53         if(salary >=0.0){
    54             this.salary = salary;
    55         }
    56     }    
    57     public void check(){
    58         System.out.println("这是salary的check的方法");
    59         System.out.println("Salary中的name="+getName()+"  薪资="+getSalary());
    60     }
    61      public double computePay() {
    62           System.out.println("计算工资,付给:" + getName());
    63           return salary/52;
    64        }
    65 }
    66 //测试类
    67 package com.test.six;
    68 
    69 public class Test {
    70     public static void main(String[] args) {
    71         Salary s = new Salary("张三", "北京", 3, 8000.0);
    72         Emploee e = new Salary("李四", "上海", 5, 10000.0);
    73         System.out.println("salary对象引用中的方法调用");
    74         s.check();
    75         s.computePay();
    76         System.out.println("emploee对象引用中的方法调用");
    77         e.check();
    78     }
    79 }

    得到的结果如下:

     1 Emploee的构造函数
     2 salary的构造函数
     3 Emploee的构造函数
     4 salary的构造函数
     5 salary对象引用中的方法调用
     6 这是salary的check的方法
     7 Salary中的name=张三  薪资=8000.0
     8 计算工资,付给:张三
     9 emploee对象引用中的方法调用
    10 这是salary的check的方法
    11 Salary中的name=李四  薪资=10000.0

    ----一旦实例化一个对象,其执行顺序,首先:

    在不涉及继承的前提下,当首次加载类时,按照如下顺序执行:
    1、按照出现顺序先后执行静态成员变量定义与静态块;
    2、按照出现顺序先后执行动态成员变量定义与动态块;
    3、执行构造函数;
    4、再次实例化对象时只执行第2、4步即可;

    在涉及到继承时,按照如下顺序执行:
    1、执行父类的静态成员变量定义与静态块,执行子类的静态成员变量与静态块
    2、执行父类非静态成员变量定义与动态块,执行父类构造方法;
    3、执行子类的非静态成员变量定义与动态块,执行子类构造方法;
    注意:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在
    调用父类构造函数中使用子类重写的方法。

    例子一:

    package com.test.seven;
    
    public class TestOne {
        private static TestOne t1 = new TestOne();
        //静态变量
        private static int i1;
        private static int i2 = 2;
    
        public TestOne(){
            i1++;
            i2++;
        }
        public static void main(String[] args) {
            TestOne t2 = new TestOne();
            System.out.println("t2.i1 = " +t2.i1);
            System.out.println("t2.i2 = "+t2.i2);    
        }
    }

    得到的结果如下:

    t2.i1 = 2
    t2.i2 = 3

    执行过程:

      首先执行给t1、i1、i2分别给予初始值null,0,0,在执行TestOne t1 = new TestOne();
    这样子i1++,i2++被执行,i1,i2都变成1,执行完毕后接着执行int i1 ,  i1,i2的值仍然是1,1,当执行int i2=2时,i2被赋予了值,即i1=1,i2=2;再执行
    TestOne t2 = new TestOne(),i1,i2在执行++,此时i1=2,i2=3,输出i1,i2,结果就是:t2.i1=2,t2.i2=3通过上面代码可以知道:
    系统默认的给予比通过等号的赋予先执行。

    例子二:

    package com.test.seven;
    
    public class TestOne {
        private static TestOne t1 = new TestOne();
        //静态变量
        private static int i1;
        private static int i2 = 2;
        //静态块
        static{
            System.out.println("静态块");
        }
        //动态块
        {
            System.out.println("动态块");
        }
        public TestOne(){
            i1++;
            System.out.println("i1--------------"+i1);
            i2++;
            System.out.println("i2--------------"+i2);
        }
        public static void main(String[] args) {
            TestOne t2 = new TestOne();
            System.out.println("t2.i1 = " +t2.i1);
            System.out.println("t2.i2 = "+t2.i2);
            
        }
    }

    得到的结果如下:

    1 动态块
    2 i1--------------1
    3 i2--------------1
    4 静态块
    5 动态块
    6 i1--------------2
    7 i2--------------3
    8 t2.i1 = 2
    9 t2.i2 = 3
  • 相关阅读:
    网线接线分类
    MongoDB修改用户密码
    win10计算器和商店英文改中文
    电脑微信双开
    ajax
    get和post的区别
    javascript中各种继承方式的优缺点
    原型
    高阶函数的封装
    深浅拷贝
  • 原文地址:https://www.cnblogs.com/FanSunny/p/5543431.html
Copyright © 2020-2023  润新知