java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java之继承多态

Java入门之继承多态使用及说明

作者:小菘爱编程

文章概述Java继承与多态的核心概念,包括继承的共性抽取、子类父类关系、super关键字的使用、构造方法与代码块执行顺序,以及向上转型、动态绑定和重写机制,最后预告多态内容并附练习题

Java继承多态

本文主要讲述继承多态的基本知识,后续会专门出代码篇

1.继承

public class Dog {
    public String name;
    public int age;
    public void run(){
        System.out.println(this.name+"正在玩球");
    }
}
 class Cat {
     public String name;
     public int age;

     public void run() {
         System.out.println(this.name + "正在奔跑");
     }
 }

其中我们不难发现狗和猫这两个类有太多的重合,所以为了代码的简化优化,我们可以将两个类相同的进行抽取,定义出新的一个类"Animal"。

public class Text extends Animal {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.run("小黄");
    }
}
 class Cat extends Animal {

 }
 class Dog extends Animal{

 }
 class Animal{
     public String name;
     public int age;

     public void run(String name) {
         this.name=name;
         System.out.println(this.name + "正在奔跑");
     }
 }

输出结果:小黄正在奔跑

其中"extends"关键字代表继承的含义,这样我们就实现了代码的简洁优化。

在Java中子类是继承父类的,上述代码狗和猫就是子类,动物是父类。

public class Text extends Animal {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat("小黄");
    }
}
 class Dog extends Animal{
    public void eat(String name){
        this.name=name;
        System.out.println(this.name+"正在吃狗粮");
    }

 }
 class Animal{
     public String name;
     public int age;
     public void eat(String name){
         this.name=name;
         System.out.println(this.name+"正在吃饭");
     }
 }

输出:小黄正在吃狗粮

如果访问的成员方法子类中有,优先访问自己的成员变量

同理我们也可以推导出:如果访问的成员变量子类中有,优先访问自己的成员变量

public class Base {
   public void methodA(){
       System.out.println("Base中的methodA()");
   }
}
public class Derived extends Base{
   public void methodB(){
       System.out.println("Derived中的methodB()方法");
   }
   public void methodC(){
       methodB(); // 访问子类自己的methodB()
       methodA(); // 访问父类继承的methodA()
// methodD(); // 编译失败,在整个继承体系中没有发现方法methodD()
   }
}

2.super关键字

super关键字是专门用来访问父类的成员变量与this关键字的用法基本相同

示例:

public class Text {
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.text();
    }
}
class Dog extends Animal{
    public void text(){
        super.eat("大黑",10);
    }
}
class Animal{
    public String name;
    public int age;
    public void eat(String name,int age){
        this.age=age;
        this.name=name;
        System.out.println(this.name+this.age+"岁"+"正在吃饭");
    }
}

输出:大黑10岁正在吃饭

public class Text {
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.text();
    }
}
class Dog extends Animal{
    public String name="huang";
    public void text(){
        System.out.println(super.name);
    }
}
class Animal{
    public String name="大黑";
    public int age;
    }

输出:大黑

3.子类父类的构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法

class Dog extends Animal{
    public String name="huang";

    public Dog(String name, int age) {
        super(name, age);
    }
}
class Animal{
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

如果父类出现了构造方法且带参数子类必须也需要出现构造方法,且需要将父类的构造方法的参数值初始化用super()关键字。

class Dog extends Animal{
    public String name="huang";

    public Dog(String name, int age) {
    }
}
class Animal{
    public String name;
    public int age;

    public Animal() {
        this.name = name;
        this.age = age;
    }

如果父类的构造方法没有参数则不需要子类必须使用super(),因为系统会默认给一个super()或者可以不写子类的构造方法系统也会默认有子类的构造方法。

4.代码块与方法的执行顺序

代码块有静态代码块和实例的代码块

static
    {
        System.out.println("a");
    }//静态
    
    {
        System.out.println("a");
    }//实例

如果一个程序有代码块,构造方法,子类父类顺序是怎样的呢?

class Person {
   public String name;
   public int age;
   public Person(String name, int age) {
       this.name = name;
       this.age = age;
       System.out.println("cccc");
   }
   {
       System.out.println("bbbb");
   }
   static {
       System.out.println("aaaa");
   }
}
public class Text{
   public static void main(String[] args) {
       Person person1 = new Person("2",10);
       System.out.println("============================");
       Person person2 = new Person("1",20);
   }
}

输出:

aaaa
bbbb
cccc
bbbb
cccc

所以静态代码块只执行一次!并优先执行!

在使用访问限定符时我们要尽可能小范围,因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限. 例如如果一个方法能用 private, 就尽量不要用 public。

5.向上转型

这里使用于子类访问父类的对象

public class Text {
    public static void main(String[] args) {
        Animal animal=new Dog();
    }
}
class Dog extends Animal{

}
class Animal{

}//直接转型
public class Text {
    public static void main(String[] args) {
        Dog dog=new Dog();
        fun(dog);

    }
    public static void fun(Animal animal){

    }

}//利用方法转型
public class Text {
    public static void main(String[] args) {
        Animal animal=fun();
    }
    public static Animal fun(){
        Dog dog=new Dog();
        return dog;

    }

}//利用返回值

当子类有父类没有的成员方法时,不能用父类的引用指向子类的成员方法

public class Text {
    public static void main(String[] args) {
        Animal animal=fun();
        animal.bark();//编译器会报错
    }
    public static Animal fun(){
        Dog dog=new Dog();
        return dog;

    }

}
class Dog extends Animal{
    public void bark(){
        System.out.println("狗叫");
    }

}

6.动态绑定

当子类完成了向上转型,子类与父类的方法构成了重写,此时animal.bark()就要调用子类的成员方法

重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 类名返回值和形参都不能改变

示例:

public class Text {
    public static void main(String[] args) {
        Animal animal=new Dog("小黄",10);
        animal.eat();

    }
}
     class Animal {
        public String name;
        public int age;

        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public void eat() {
            System.out.println(this.name + " 正在吃饭.....");
        }
    }

     class Dog extends Animal {
        public Dog(String name, int age) {
            super(name, age);
        }

        public void bark() {
            System.out.println(this.name + " 正在汪汪汪叫...");
        }

        @Override
        public void eat() {
            System.out.println(this.name + " 正在吃狗粮...");
        }

    }

输出:小黄 正在吃狗粮…

结语

以上是Java继承的内容,下次小编会带来多态的内容,希望读者们多提建议。

最后小编整理了一道题目

如下代码的 结果是什么 ?
class Base {
  Base() {
  	System.out.print("Base"); 
  }
}

public class Alpha extends Base {
 
  public static void main( String[] args ) {
    new Alpha();//1
    //调用父类无参的构造方法
    new Base();//2
  } 
}

A.Base
B.BaseBase
C.编译失败
D.代码运行但没有输出
E.运行时抛出异常

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文