zoukankan      html  css  js  c++  java
  • Java_继承、super、this、抽象类

    1. 继承初识

    package cn.itcast.day09.demo01;
    
    // 定义一个父类:员工
    public class Employee {
    
        public void method() {
            System.out.println("方法执行!");
        }
    
    }
    package cn.itcast.day09.demo01;
    
    // 定义了一个员工的子类:讲师
    public class Teacher extends Employee {
    
    } 
    package cn.itcast.day09.demo01;
    
    // 定义了员工的另一个子类:助教
    public class Assistant extends Employee {
    }
    package cn.itcast.day09.demo01;
    
    /*
    在继承的关系中,“子类就是一个父类”。也就是说,子类可以被当做父类看待。
    例如父类是员工,子类是讲师,那么“讲师就是一个员工”。关系:is-a。
    
    定义父类的格式:(一个普通的类定义)
    public class 父类名称 {
        // ...
    }
    
    定义子类的格式:
    public class 子类名称 extends 父类名称 {
        // ...
    }
     */
    public class Demo01Extends {
    
        public static void main(String[] args) {
            // 创建了一个子类对象
            Teacher teacher = new Teacher();
            // Teacher类当中虽然什么都没写,但是会继承来自父类的method方法。
            teacher.method();
    
            // 创建另一个子类助教的对象
            Assistant assistant = new Assistant();
            assistant.method();
        }
    
    }
    

    2. 继承中访问成员变量

    package cn.itcast.day09.demo02;
    
    public class Fu {
    
        int numFu = 10;
    
        int num = 100;
    
        public void methodFu() {
            // 使用的是本类当中的,不会向下找子类的
            System.out.println(num);
        }
    
    }
    
    package cn.itcast.day09.demo02;
    
    public class Zi extends Fu {
    
        int numZi = 20;
    
        int num = 200;
    
        public void methodZi() {
            // 因为本类当中有num,所以这里用的是本类的num
            System.out.println(num);
        }
    
    }
    package cn.itcast.day09.demo02;
    
    /*
    在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:
    
    直接通过子类对象访问成员变量:
        等号左边是谁,就优先用谁,没有则向上找。
    间接通过成员方法访问成员变量:
        该方法属于谁,就优先用谁,没有则向上找。
     */
    public class Demo01ExtendsField {
    
        public static void main(String[] args) {
            Fu fu = new Fu(); // 创建父类对象
            System.out.println(fu.numFu); // 只能使用父类的东西,没有任何子类内容
            System.out.println("===========");
    
            Zi zi = new Zi();
    
            System.out.println(zi.numFu); // 10
            System.out.println(zi.numZi); // 20
            System.out.println("===========");
    
            // 等号左边是谁,就优先用谁
            System.out.println(zi.num); // 优先子类,200
    //        System.out.println(zi.abc); // 到处都没有,编译报错!
            System.out.println("===========");
    
            // 这个方法是子类的,优先用子类的,没有再向上找
            zi.methodZi(); // 200
            // 这个方法是在父类当中定义的,
            zi.methodFu(); // 100
        }
    
    }
    

    3. this super

    package cn.itcast.day09.demo03;
    
    public class Fu {
    
        int num = 10;
    
    }
    package cn.itcast.day09.demo03;
    
    public class Zi extends Fu {
    
        int num = 20;
    
        public void method() {
            int num = 30;
            System.out.println(num); // 30,局部变量
            System.out.println(this.num); // 20,本类的成员变量
            System.out.println(super.num); // 10,父类的成员变量
        }
    
    } 
    package cn.itcast.day09.demo03;
    
    /*
    局部变量:         直接写成员变量名
    本类的成员变量:    this.成员变量名
    父类的成员变量:    super.成员变量名
     */
    public class Demo01ExtendsField {
    
        public static void main(String[] args) {
            Zi zi = new Zi();
    
            zi.method();
        }
    
    }

    3.1 super的使用

    package cn.itcast.day09.demo08;
    
    public class Fu {
    
        int num = 10;
    
        public void method() {
            System.out.println("父类方法");
        }
    
    }
    
    package cn.itcast.day09.demo08;
    
    /*
    super关键字的用法有三种:
    1. 在子类的成员方法中,访问父类的成员变量。
    2. 在子类的成员方法中,访问父类的成员方法。
    3. 在子类的构造方法中,访问父类的构造方法。
     */
    public class Zi extends Fu {
    
        int num = 20;
    
        public Zi() {
            super();
        }
    
        public void methodZi() {
            System.out.println(super.num); // 父类中的num
        }
    
        public void method() {
            super.method(); // 访问父类中的method
            System.out.println("子类方法");
        }
    
    } 

    3.2 this的使用

    package cn.itcast.day09.demo09;
    
    public class Fu {
    
        int num = 30;
    
    }
    package cn.itcast.day09.demo09;
    
    /*
    super关键字用来访问父类内容,而this关键字用来访问本类内容。用法也有三种:
    
    1. 在本类的成员方法中,访问本类的成员变量。
    2. 在本类的成员方法中,访问本类的另一个成员方法。
    3. 在本类的构造方法中,访问本类的另一个构造方法。
    在第三种用法当中要注意:
    A. this(...)调用也必须是构造方法的第一个语句,唯一一个。
    B. super和this两种构造调用,不能同时使用。
     */
    public class Zi extends Fu {
    
        int num = 20;
    
        public Zi() {
    //        super(); // 这一行不再赠送
            this(123); // 本类的无参构造,调用本类的有参构造
    //        this(1, 2); // 错误写法!
        }
    
        public Zi(int n) {
            this(1, 2);
        }
    
        public Zi(int n, int m) {
        }
    
        public void showNum() {
            int num = 10;
            System.out.println(num); // 局部变量
            System.out.println(this.num); // 本类中的成员变量
            System.out.println(super.num); // 父类中的成员变量
        }
    
        public void methodA() {
            System.out.println("AAA");
        }
    
        public void methodB() {
            this.methodA();
            System.out.println("BBB");
        }
    
    }  

    4. 继承中访问成员方法

    package cn.itcast.day09.demo04;
    
    public class Fu {
    
        public void methodFu() {
            System.out.println("父类方法执行!");
        }
    
        public void method() {
            System.out.println("父类重名方法执行!");
        }
    
    }
    
    package cn.itcast.day09.demo04;
    
    public class Zi extends Fu {
    
        public void methodZi() {
            System.out.println("子类方法执行!");
        }
    
        public void method() {
            System.out.println("子类重名方法执行!");
        }
    
    }
    package cn.itcast.day09.demo04;
    
    /*
    在父子类的继承关系当中,创建子类对象,访问成员方法的规则:
        创建的对象是谁,就优先用谁,如果没有则向上找。
    
    注意事项:
    无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。
    
    重写(Override)
    概念:在继承关系当中,方法的名称一样,参数列表也一样。
    
    重写(Override):方法的名称一样,参数列表【也一样】。覆盖、覆写。
    重载(Overload):方法的名称一样,参数列表【不一样】。
    
    方法的覆盖重写特点:创建的是子类对象,则优先用子类方法。
     */
    public class Demo01ExtendsMethod {
    
        public static void main(String[] args) {
            Zi zi = new Zi();
    
            zi.methodFu();
            zi.methodZi();
    
            // 创建的是new了子类对象,所以优先用子类方法
            zi.method();
        }
    
    }
    

    5. 方法覆盖重写

    package cn.itcast.day09.demo05;
    
    public class Fu {
    
        public String method() {
            return null;
        }
    
    }
    package cn.itcast.day09.demo05;
    
    public class Zi extends Fu {
    
        @Override
        public String method() {
            return null;
        }
    
    }
    package cn.itcast.day09.demo05;
    
    /*
    方法覆盖重写的注意事项:
    
    1. 必须保证父子类之间方法的名称相同,参数列表也相同。
    @Override:写在方法前面,用来检测是不是有效的正确覆盖重写。
    这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。
    
    2. 子类方法的返回值必须【小于等于】父类方法的返回值范围。
    小扩展提示:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。
    
    3. 子类方法的权限必须【大于等于】父类方法的权限修饰符。
    小扩展提示:public > protected > (default) > private
    备注:(default)不是关键字default,而是什么都不写,留空。
     */
    public class Demo01Override {
    
    }
    

    6. 继承中的构造方法

    package cn.itcast.day09.demo07;
    
    public class Fu {
    
        public Fu() {
            System.out.println("父类无参构造");
        }
    
        public Fu(int num) {
            System.out.println("父类有参构造!");
        }
    
    } 
    package cn.itcast.day09.demo07;
    
    public class Zi extends Fu {
    
        public Zi() {
            super(); // 在调用父类无参构造方法
    //        super(20); // 在调用父类重载的构造方法
            System.out.println("子类构造方法!");
        }
    
        public void method() {
    //        super(); // 错误写法!只有子类构造方法,才能调用父类构造方法。
        }
    
    } 
    package cn.itcast.day09.demo07;
    
    /*
    继承关系中,父子类构造方法的访问特点:
    
    1. 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造。
    2. 子类构造可以通过super关键字来调用父类重载构造。
    3. super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
    总结:
    子类必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。
     */
    public class Demo01Constructor {
    
        public static void main(String[] args) {
            Zi zi = new Zi();
        }
    
    }
    

    7. 抽象方法和抽象类

    package cn.itcast.day09.demo11;
    
    /*
    抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
    抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。
    
    如何使用抽象类和抽象方法:
    1. 不能直接创建new抽象类对象。
    2. 必须用一个子类来继承抽象父类。
    3. 子类必须覆盖重写抽象父类当中所有的抽象方法。
    覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号。
    4. 创建子类对象进行使用。
     */
    public abstract class Animal {
    
        // 这是一个抽象方法,代表吃东西,但是具体吃什么(大括号的内容)不确定。
        public abstract void eat();
    
        // 这是普通的成员方法
    //    public void normalMethod() {
    //
    //    }
    
    }
    package cn.itcast.day09.demo11;
    
    public class DemoMain {
    
        public static void main(String[] args) {
    //        Animal animal = new Animal(); // 错误写法!不能直接创建抽象类对象
    
            Cat cat = new Cat();
            cat.eat();
        }
    
    }
    package cn.itcast.day09.demo11;
    
    public class Cat extends Animal {
    
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
    
    }
    
    /*
    一个抽象类不一定含有抽象方法,
    只要保证抽象方法所在的类是抽象类,即可。
    
    这样没有抽象方法的抽象类,也不能直接创建对象,在一些特殊场景下有用途。
     */
    
  • 相关阅读:
    15. DML, DDL, LOGON 触发器
    5. 跟踪标记 (Trace Flag) 834, 845 对内存页行为的影响
    4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志
    14. 类似正则表达式的字符处理问题
    01. SELECT显示和PRINT打印超长的字符
    3. 跟踪标记 (Trace Flag) 1204, 1222 抓取死锁信息
    2. 跟踪标记 (Trace Flag) 3604, 3605 输出DBCC命令结果
    1. 跟踪标记 (Trace Flag) 1117, 1118 文件增长及空间分配方式
    0. 跟踪标记 (Trace Flag) 简介
    SpringBoot + Redis + Shiro 实现权限管理(转)
  • 原文地址:https://www.cnblogs.com/yzg-14/p/12594882.html
Copyright © 2011-2022 走看看