java 特性之--继承

继承

继承的理解

简单理解继承:继承分为父类子类,子类继承父类,子类可以使用父类中public(公有的) 的成员属性和成员方法,但是子类中也可以有属于自己的成员变量和成员方法,但是父类不可以调用子类中的属性和方法

具体场景:鸟类 (父类)一个抽象的概念,鸟可以有自己的(属性)姓名,基本功能(方法)是吃饭,睡觉
================================================
鹰类(子类),鹰类继承鸟类,鹰类可以调用鸟类里面的(属性)姓名,也可以继承里面的(方法)基本功能,吃饭,睡觉,但是鹰类有个自己的专属功能就是飞行(举个例子,大部分鸟都会飞)
================================================
鸵鸟类(子类),鸵鸟类继承鸟类,和上面类似,继承基础的属性和功能都具备,鸵鸟类自己的专属技能就是奔跑(找到一个不会飞的鸟,差异化)

以上对继承的简单理解

继承的语法

父类

public class fu{
   //属性(成员变量)
   //功能(成员方法)
}

子类–继承上面父类

public class zi extends fu{
   //属性(成员变量)
   //功能(成员方法)
}

例子:

定义一个鸟类(父类)

/**
 * @Classname : bird
 * @Description : TODO 鸟类 - 父类
 * @Author : [email protected]
 */
public class bird {
    //两个成员变量
    public String name; //姓名
    public int age; // 年龄

    //无参数的构造方法
    public bird() {
    }
    //两个参数的构造方法
    public bird(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //两个成员方法
    public void eat(){
        System.out.println(this.name+"基本功能:会吃");
    }
    public void sleep(){
        System.out.println(this.name+"基本功能:会睡觉");
    }
}

定义一个鹰类(子类),继承鸟类

/**
 * @Classname : hawk
 * @Description : TODO 鹰类 - 继承鸟类
 * @Author : [email protected]
 */
public class hawk extends bird {

    //定义一个成员变量
    public int altitude;//飞行高度

    //无参数的构造方法
    public hawk() {
    }

    //三个带参数的构造方法
    public hawk(String name, int age, int altitude) {
        //super是调用父类当中的构造方法
        super(name, age);
        this.altitude = altitude;
    }
    //鹰类的功能飞行
    public void fly() {
        System.out.println(this.name + "," + this.age + "岁" + "可以飞行");
        System.out.println("飞行高度" + this.altitude + "米");
    }
}

测试类,实例子化调用上面类

/**
 * @Classname : test
 * @Description : TODO 测试类
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化bird
        bird bird = new bird("鸟",3);
        bird.eat();
        bird.sleep();
        System.out.println("===================");
        //实例化hawk类
        hawk hawk = new hawk("鹰",1,9000);
        //调用继承的方法
        hawk.eat();
        hawk.sleep();
        hawk.fly();
    }
}

鹰类当中没定义姓名(name)和年龄(age)的成员变量,也没有定义eat和sleep方法,但是鹰类继承了鸟类,可以进行调用

运行结果;

插入一个科普:鹰能飞多高?
java 特性之--继承_第1张图片
我也不知道鹰几岁能飞,三天?就当作一岁吧java 特性之--继承_第2张图片

子类和父类成员变量名字相同时访问方式

两个关键字
super:带有super关键字修饰的方法和变量代表是父类的中的功能和属性
this:代表是自己类中的,封装笔记里面也有记录
局部变量:没有修饰符应该就是局部变量或者形式参数了

例子

定义一个父类

/**
 * @Classname : fu
 * @Description : TODO 父类
 * @Author : [email protected]
 */
public class fu {
    //定义两个成员变量
    public String name;
    public int age;

    //定义无参的构造方法
    public fu() {
    }
    //定义两个带参数的构造方法
    public fu(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //定义一个成员方法
    public void eat(){
        System.out.println(this.age + "岁的" + this.name + "正在吃");
    }
}

定义一个子类-继承上面父类

/**
 * @Classname : zi
 * @Description : TODO 子类 - 继承fu类
 * @Author : [email protected]
 */
public class zi extends fu {
    //定义两个和fu类名字相同的属性
    public String name;
    public int age;

    //定义无参数的构造方法
    public zi() {
    }
    //定义四个带参数的构造方法

    /**
     * 成员变量初始化的构造方法
     *
     * @param name  父类中name初始化
     * @param age   父类中age初始化
     * @param name1 子类中name进行初始化
     * @param age1  子类中age进行初始化
     */
    public zi(String name, int age, String name1, int age1) {
        super(name, age);//调用父类中两个参数的构造方法
        this.name = name1;
        this.age = age1;
    }
    public void eat() {
        //子类中调用父类中同名的成员变量的方式 super.变量名字
        System.out.println(super.age + "岁的" + super.name + "正在吃");
        //调用自己类里面的成员变量this.变量名
        System.out.println(this.age + "岁的" + this.name + "正在吃");
    }
}

super();,是调用父类中构造方法,例如下面的代码,就是调用父类中带有两个参数的构造方法

super(name,age);//调用父类中带有两个参数的构造方法

测试类

/**
 * @Classname : test
 * @Description : TODO 测试类
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化fu类对象
        fu fu = new fu("黄固",35);
        fu.eat();
        System.out.println("=============");
        //实例化zi类对象
        zi zi = new zi("黄固",35,"黄蓉",12);
        zi.eat();
    }
}

运行结果:
通过super关键字和this关键字能清晰知道成员变量是属于父类还是子类,具体调用过程查看zi类里面eat方法中的注释
java 特性之--继承_第3张图片

方法重写

方法重写:简单来说就是父类和子类中有一个名字返回值类型相同的方法,但是子类中和父类中输出内容不一样

例子:

定义一个父类

/**
 * @Classname : Fu
 * @Description : TODO - 父类
 * @Author : [email protected]
 */
public class Fu {
    //定义两个成员变量
    public String name; //姓名
    public int age; // 年龄

    //定义无参构造方法
    public Fu() {
    }
    //定义带两个参数的构造方法

    /**
     * 初始化两个成员变量
     * @param name 姓名
     * @param age 年龄
     */
    public Fu(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //定义一个eat方法
    public void eat(){
        System.out.println(this.age + "岁的" + this.name + "吃面条");
    }
}

定义一个子类-继承父类

/**
 * @Classname : zi
 * @Description : TODO 子类 - 继承Fu类
 * @Author : [email protected]
 */
public class zi extends Fu {
    //定义两个和Fu类相同的成员变量
    public String name;
    public int age;

    //定义无参构造方法
    public zi() {
    }

    /**
     * 四个参数的构造方法,给Fu类和zi类 成员属性初始化
     *
     * @param name  Fu类name赋值
     * @param age   Fu类age赋值
     * @param name1 zi类name赋值
     * @param age1  zi类age赋值
     */
    public zi(String name, int age, String name1, int age1) {
        super(name, age);
        this.name = name1;
        this.age = age1;
    }

    //重写Fu类里面的eat方法
    public void eat() {
        System.out.println(this.age + "岁的女儿" + this.name + "吃米饭");
    }

    //调用子类和父类中eat方法的方式
    public void show(){
        //调用zi类中重写的eat方法 this.方法名字
        this.eat();
        System.out.println("================");
        //直接调用Fu类中的eat方法 super.方法名
        super.eat();
    }
}

测试类

/**
 * @Classname : test
 * @Description : TODO - 测试类
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化Fu类
        Fu fu = new Fu("黄固",32);
        fu.eat();
        System.out.println("====================");
        //实例化子类
        zi zi = new zi("黄固",33,"黄蓉",12);
        zi.eat();
        System.out.println("=====================");
        zi.show();
    }
}

总结:

  1. Fu类中eat和zi类中eat两种输出的内容不同,Fu类eat吃面条,zi类eat输出吃米饭,这大概就是zi类对Fu类的eat方法进行重写吧
  2. 子类中调用本类中eat方法和调用Fu类中eat方法的方式,参考zi类中show方法注释

运行结果:
java 特性之--继承_第4张图片

继承中修饰符的权限

修饰符 类内部 同包内 子类内 其他中
private YES NO NO NO
default YES YES NO NO
protected YES YES YES NO
public YES YES YES YES

带有上面修饰符的成员变量和方法有些地方不能调用

同包里面测试

例子:定义一个Fu类,package com.xs.demo04;存放这个包里面,定义出几个上面修饰符成员变量

package com.xs.demo04;

/**
 * @Classname : Fu
 * @Description : TODO
 * @Author : [email protected]
 */
public class Fu {
    //定义四个不同修饰符的成员变量
       public String varpub = "我是公有变量";
      private String varpri = "我是私有变量";
    protected String varpro = "我是受保护的";
              String vardef = "我是默认的";
}

测试类:同一个包里面可以调用上面父类那些修饰符成成员变量

package com.xs.demo04;//完整的包路径.类名

/**
 * @Classname : test
 * @Description : TODO
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化对象
        Fu fu = new Fu();
        System.out.println(fu.vardef);
        System.out.println(fu.varpro);
        System.out.println(fu.varpub);
        //同一个包里面,除了私有变量,其他都能进行访问
        System.out.println("=========================");
    }
}

运行结果:
java 特性之--继承_第5张图片

同一个包里面子类是否可以访问那些成员变量

例子:定义一个子类继承上面Fu类

package com.xs.demo04;

/**
 * @Classname : zi
 * @Description : TODO
 * @Author : [email protected]
 */
public class zi extends Fu{
    //定义一个成员方法
    public void show(){
        //输出Fu类中可以访问的成员变量
        System.out.println(super.vardef);
        System.out.println(super.varpro);
        System.out.println(super.varpub);
        //同包子类中,除了private修饰的变量,其他都可以访问到
    }
}

测试类,测试输出结果

package com.xs.demo04;

/**
 * @Classname : test
 * @Description : TODO
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化对象
        zi zi = new zi();
        zi.show();
        System.out.println("=========================");
    }
}

运行结果:
java 特性之--继承_第6张图片

其他包里面建立一个子类继承Fu类可以访问的变量验证

例子:

  package com.xs.demo05;
  import com.xs.demo04.Fu;//导入Fu类的包路径和继承的类名
/**
 * @Classname : Zi02
 * @Description : TODO -子类02 继承 demo04里面的Fu类
 * @Author : [email protected]
 */
public class Zi02 extends Fu {
    public void show(){
        System.out.println(super.varpro);
        System.out.println(super.varpub);
        //不同包里的子类,继承其他包里面的父类能访问的只有,public 和 default(默认的类)
    }
}

调用上面的类

package com.xs.demo05;

/**
 * @Classname : test
 * @Description : TODO
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化Zi02类
        Zi02 zi02 = new Zi02();
        zi02.show();
    }
}

运行结果:
java 特性之--继承_第7张图片

相信你看了上面代码感觉不是很懂?

没事,理解下面的四点在去看看?

总结四点

  1. 同类中四种权限符修饰的成员变量都可以进行访问,private是不能直接进行访问的,除了类里面任何地方都不行哦~
  2. public哪里都可以进行访问
  3. 默认的(default),只有同类同一个包里面可以进行访问,子类继承的也可以访问
  4. protected是同包里面子类继承或者不同包里面子类继承时才能进行访问,其他包里面子类没有继承不能访问

this调用自己类中的构造方法

this();,是调用类中构造方法,根据括号里的参数调用类中那个构造方法

例子:定义一个人类(Person)

package com.xs.demo06;

/**
 * @Classname : Person
 * @Description : TODO - 人类
 * @Author : [email protected]
 */
public class Person {
    //定义四个人类基本属性
    private String name; //姓名
    private int age;//年龄
    private String sex;//性别
    private String jop;//职业
    //无参数的构造方法
    public Person() {
        System.out.println("无参数的构造方法");
    }
    //带一个参数的构造方法
    public Person(String name){
        this();//调用上面无参数构造方法
        this.name = name;
    }
    //带2个参数的构造方法
    public Person(String name,int age){
        this(name);//调用上面一个参数的构造方法
        this.age = age;
    }
    //带3个参数的构造方法
    public Person(String name,int age,String sex){
        this(name,age);//调用上面2个参数的构造方法
        this.sex = sex;
    }
    //带四个参数的构造方法
    public Person(String name,int age,String sex,String jop){
        this(name,age,sex);//调用上面3个参数的构造方法
        this.jop = jop;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", jop='" + jop + '\'' +
                '}';
    }
}

注意注释

测试结果类

package com.xs.demo06;

/**
 * @Classname : test
 * @Description : TODO 测试类
 * @Author : [email protected]
 */
public class test {
    public static void main(String[] args) {
        //实例化对象Person
        Person person = new Person("小肆",18,"女","学生");
        System.out.println(person);
    }
}

调用Person类当中四个参数的构造方法,然后套娃式进行调用,直到调用无参数构造方法,上面代码应该可以帮助你理解this.,调用类中构造方法的方式
运行结果:
在这里插入图片描述

你可能感兴趣的:(java,SE面向对象,java,开发语言)