Java — 类与继承

  • Post author:
  • Post category:java




继承的实现



1.继承概述
  • 继承就是从已有类(

    基类

    )的基础上产生一个新的类(

    派生类

  • 派生类通过继承自动拥有基

    类的属性和方法

    ,继承是实现类的重用、软件复用的重要手段。


2.基类与派生类的关系

  • 派生类是基类的特化,而基类是派生类的泛化
  • 基类和派生类是相对的


3.继承的特性
  • 派生类拥有父类

    非 private

    的属性、方法。
  • 派生类可以拥有自己的属性和方法,即子类可以对基类进行

    扩展。


4.继承的实现
  • 语法格式

    class 基类 {
        .....
    }
    class 派生类 extends 基类 {
        .....
    }
    
  • 要点


    • 一个类只能有一个直接基类

      (但是可以有多个间接基类)

    • final

      修饰的类不能有派生类
    • Object类是所有Java类的顶级基类(未指派基类时发挥作用)
  • public class Person {
        //一个类如果被final修饰则不能再去定义派生类
        private String name;
        private String gender;
        protected int age;//本类以及派生类内可访问,同包可访问
        public int num = 20; //可以给属性赋初值,先于构造方法执行
    
        public void steName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    
        public void setGender(String gender){
            this.gender = gender;
        }
        public String getGender(){
            return gender;
        }
    
        public void setAge(int age){
            this.age = age;
        }
        public int getAge(){
            return age;
        }
    
        public void think(){
            System.out.println("正在思考");
        }
    }
    
    public class Teacher extends Person {
        //一个类只允许有一个基类(可以有多个间接基类)
        //未指定继承类则继承object类
        //定义新增的属性与方法
        private String major;
        private String address;
        private double salary;
        //隐藏同名基类成员(同名属性,静态方法)
        private int num = 30;
    
        //定义派生类的构造方法
        //派生类默认调用无参构造方法
        public Teacher(){
            //调用基类的有参构造方法,放在第一行
            super("无名氏", "男", 18);
            System.out.println("派生类的无参构造方法");
        }
    
        public void setMajor(String major) {
            this.major = major;
        }
        public String getMajor() {
            return major;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
        public String getAddress() {
            return address;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
        public double getSalary() {
            return salary;
        }
    
        public void teach(){
            think();//通过继承直接调用
            System.out.println("正在教课");
        }
    
        //派生类内,可以直接通过属性名或方法名访问基类非私有方法属性与方法(继承)
        public int getNum() {
            return num;
        }
    }
    


4.继承的过程
  • 吸收基类成员

    • 派生类把基类全部的成员(不包括构造方法)接收过来。
  • 增加派生类成员

    • 是派生类对基类功能的扩展
  • 调整基类成员

    • 隐藏基类同名成员


5.不同修饰符下访问权限

访问权限修饰符

本类****内

派生类内

本类和派生类外

public







protected




同包 不同包



×

private



×

×



构造方法的调用



1.调用方式
  • 在基类中定义无参数的构造方法。

    (创建派生类对象是会自动调用基类构造方法,且先执行基类)
  • 在派生类类中显式调用基类中定义的构造方法。


2. super关键字
  • 用于调用基类的方法或属性(不固定位置)

    super.属性   super.方法
    
  • 用于调用基类的构造方法**(只能放在第一行)**

    super()   super(参数)
    
  • 使用super()、super(参数)的形式


  • super只能访问基类中的非private类型的属性或方法。



方法重写



1.概要
  • 派生类对基类中定义的方法进行重新实现称为方法重写

  • 重写的主要优点是能够定义某个派生类型特有的行为

    //定义基类
    public class Person {
        //一个类如果被final修饰则不能再去定义派生类
        private String name;
        private String gender;
        protected int age;
        public int num = 20; 
    
        String str;//包权限(默认权限)
    
        //定义基类的构造方法
        public  Person(){
            System.out.println("基类的无参构造方法");
        }
    
        public void display(){
            System.out.println("基类的display方法");
        }
    }
    
    
    //定义派生类要指定基类的名称
    public class Teacher extends Person {
        //一个类只允许有一个基类(可以有多个间接基类)
        //未指定继承类则继承object类
        //定义新增的属性与方法
        private String major;
        private String address;
        private double salary;
        //隐藏同名基类成员(同名属性,静态方法)
        private int num = 30;
    
        //定义派生类的构造方法
        //派生类默认调用无参构造方法
        public Teacher(){
            //调用基类的有参构造方法,放在第一行
            super("无名氏", "男", 18);
            System.out.println("派生类的无参构造方法");
        }
    
        /*派生类内重写方法
         *返回值类型必须相同
         *传参必须相同
         */
        public void display(){
            System.out.println("派生类内重写的方法");
        }
        //返回值类型与基类一致或者为基类返回值类型的子类类型
        @Override //检查某个方法是不是对基类重写
        public String fun() {
            return "abc";
        }
    
        /*final的作用
         *定义常量,不允许被修改
         * 修饰一个类,不可被扩展
         * 定义不可被重写的方法
         */
    }
    


2.重写规则
  • 重写的方法返回值类型是基类方法返回值类型的

    子类或者相同;
  • 重写的方法具有

    相同的方法名

  • 重写的方法

    参数列表必须相同

  • 不能重写被标识为

    final

    的方法;
  • 重写的方法

    不能缩小访问权限

  • 不能重写

    基类私有

    的方法。


3.向上转型
  • 简单来说就是子类对象转化为父类对像。父类引用指向子类对象

  • 可以调用

    基类中定义

    的属性和方法

  • 无法调用派生类中定义而

    基类中没有

    的方法。

    //向上转型(顺序不可转)
    //person2存在两个类型,一个是编译类型(Person),一个是运行类型(Teacher)
    //可以调用两者都有的方法(包括继承过来的方法,与重写方法,不可继承的也不能调用)
    //指向子类对象的基类对象的引用,不能调用派生类中新生的方法
    Person person2 = new Teacher();
    person2.display();
    //判断person运行时的类型是否为teacher
    System.out.println(person2 instanceof Teacher);
    person2 = new Student();
    System.out.println(person2 instanceof Teacher);
    
    Person person3 = new Person();
    //同包非本类(派生类),用创建对象访问
    person3.str = "abc";
    



关于包



1.概述
  • 概念:用于区别类名的命名空间。
  • 如果希望自己的类从属于一个包,可以使用package关键字**(package语句必须放在源程序的除注释外的第一行)**


2.包的创建与引用
  • 包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。
  • 通过import关键字引入包**(import语句,必须位于package和类声明之间。)**



版权声明:本文为m0_60610120原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。