• 抽象与接口的理解


    继承的概念

    继承描述的是事物之间的所属关系,通过继承可是使多种事物之间形成一种关系体系
    类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,如果想声明一个类继承另一个类,需要使用extends关键字

    class Animal{
        String name;
        public void show() {
            System.out.println(name+"发出了叫声");
        }
    }
    //Dog类继承自Animal类
    class Dog extends Animal{
        //打印一个name的方法
        public void printName() {
            System.out.println("这个动物现在是"+name);
        }
    }
    public class Example01 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.name="老黑";
            dog.printName();
            dog.show();    
        }
    }

    注 意:
    1. 在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类
    2. 多个类可以继承同一个父类
    3. 在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类
    4. 在Java中,子类和父类是一种相对概念,也就是说一个类是某个父类的同时,也可以是另外一个类的子类。

    重写父类方法

    在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型

    class Animal{
        public void show() {
            System.out.println("发出了叫声");
        }
    }
    //Dog类继承自Animal类
    class Dog extends Animal{
        @Override     //重写父类show()方法
        public void show() {
            System.out.println("汪汪汪");
        }
    }
    public class Example01 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.show();
        }
    }

    注 意:
    子类重写父类方法时,不能使用父类中被重写的方法更严格的访问权限,如:父类中的方法是public的,子类的方法就不能是private的

    super关键字

    Java中专门提供了一个super关键字用来访问父类的成员

    1. 使用super关键字访问父类的成员变量和成员方法

      super.成员变量
      super.成员方法([参数1,参数2...])

    案例学习

    class Animal{
                String name="动物";
                public void show() {
                    System.out.println(name+"发出了叫声");
                }
            }
            //Dog类继承自Animal类
            class Dog extends Animal{
                String name="黑狗";
                //打印一个name的方法
                public void printName() {
                    System.out.println("这个动物现在是"+super.name);
                }
                @Override
                public void show() {
                    super.show();
                }
            }
            public class Example01 {
                public static void main(String[] args) {
                    Dog dog = new Dog();
                    dog.printName();
                    dog.show();        
                }
            }

    2. 使用super关键字访问父类的构造方法,注意通过super调用父类的构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次

      super.([参数1,参数2...])

    class Animal{
        //定义Animal的有参构造
        public Animal(String name) {
            System.out.println("我是一只"+name);
        }
    }
    class Dog extends Animal{
        public Dog() {
            super("老王");    //调用父类有参的构造方法
        }
    }
    public class Example02 {
        public static void main(String[] args) {
            Dog dog = new Dog();
        }
    }

    在定义一个类时,如果没有特殊需求,尽量在类中定义一个无参的构造方法,避免被继承时出现错误

     final关键字

    final关键字可用于修饰类、变量和方法,它有"无法改变"或者"最终"的含义,因此被finnal修饰的类、变量和方法具有以下特性:

    1. finnal修饰的类不能被技能
    2. finnal修饰的方法不能被子类重写
    3. finnal修饰的变量(成员变量和局部变量)是常量,只能赋值一次

    抽象类

    Java允许在定义方法时不写方法体。不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰

        abstract void show();                 //定义抽象方法show()

    当一个类中包含了抽象方法,该类必须使用**abstract**关键字来修饰,使用abstract关键字修饰的类为抽象类

    //定义抽象类Animal
    abstract class Animal{
        abstract int show();
    }

    在定义抽象类时需要注意,包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法,只需使用abstract关键字来修饰即可。另外,抽象类时不可以被实例化的,因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用。如果想调用抽象类中定义的方法,则需要创建一个子类,在子类中将抽象类中的抽象方法进行实现

    //定义抽象类
    abstract class Animal{
        abstract void show();
    }
    //定义Dog类继承抽象类Animal
    class Dog extends Animal{
        @Override
        void show() {
            System.out.println("这是重写的抽象类");
        }
    }
    public class Example01 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.show();
        }
    }

    接口

    如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方法来定义,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象

    [public] interface 接口名 [extends 接口1,接口2...]{
        [public] [static ] [final] 数据类型 常量名 = 常量值;
        [public] [abstract] 返回值 抽象方法名(参数列表);
    }

    在一个接口中可以有多个父接口,它们之间用逗号隔开。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口。接口中的变量默认使用"public static final"来修饰,即全局常量;接口中定义的方法默认使用"public abstract"来修饰,即抽象方法。如果接口声明为public,则接口中的变量和方法全部为public

    由于接口中的方法都是抽象方法,因此不能通过实例化对象的方法来调用接口中的方法,此时需要定义一个类,并使用implements关键字实现接口中所有的方法。一个类可以在继承另一个类的同时实现多个接口,这些接口在implements子句中要是用英文逗号(,)隔开。接口的实现类声明格式如下

        [<修饰符>] class<类名> [extends <超类名>]  [implements <接口1>,<接口2>,...]
    //定义Animal接口
    interface Animal{
        //定义全部变量,其默认修饰为public static final
        String ANIMAL_BEHAVIOR="动物的行为";
        //定义抽象方法breathe(),其默认修饰为public abstract
        void breathe();
        //定义抽象方法run
        void run();
    }
    //Dog类实现了Animal的接口
    class Dog implements Animal{
        @Override
        public void breathe() {
            System.out.println(ANIMAL_BEHAVIOR+"在玩耍");
        }
        @Override
        public void run() {
            System.out.println(ANIMAL_BEHAVIOR+"在奔跑");
        }
    }
    public class Example01 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.breathe();
            dog.run();
        }
    }

    注意:一个类实现一个接口,必须给出接口中所有方法的实现,如果不能实现某方法,也必须写出一个空方法

    在程序中还可以定义一个接口使用extends关键字去继承另一个接口

    //定义animal接口
    interface Animal{
        //定义全部常量,其默认修饰为public static final
        String ANIMAL_BEHAVIOR = "动物的行为";
        //定义抽象方法breathe(),其默认修饰为public abstract
        void breathe();
        //定义抽象方法run();
        void run();
    }
    //定义了LandAnimal接口
    interface LandAnimal extends Animal{
        void liveOnLand();
    }
    //定义Dog类实现Animal接口
    class Dog implements LandAnimal{
        //实现breath方法
        @Override
        public void breathe() {
            System.out.println(ANIMAL_BEHAVIOR+": 狗在呼吸");
        }
        //实现run方法
        @Override
        public void run() {
            System.out.println(ANIMAL_BEHAVIOR+": 狗在奔跑");
        }
        //实现liveOnLand方法
        @Override
        public void liveOnLand() {
            System.out.println("狗是陆上动物");
        }
    }
    //测试类
    public class Example01 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            //使用对象名.常量名的方式输出接口中的常量
            System.out.println(dog.ANIMAL_BEHAVIOR);
            //使用接口名.常量名的方式输出接口中的常量
            System.out.println(Animal.ANIMAL_BEHAVIOR);
            dog.breathe();        //调用Dog类重写的breathe方法
            dog.run();            //调用Dog类重写的run方法
            dog.liveOnLand();    //调用Dog类重写的liveOnLand方法
        }
    }

    总结接口的特点:

    1. 接口中的方法都是抽象的,不能实例化对象
    2. 接口中的属性只能是常量
    3. 当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法。
    4. 一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开
    5. 一个接口可以通过extends关键字继承多个接口,接口之间用逗号隔开
    6. 一个类在继承另一个类的同时还可以实现接口,此时,extends关键字必须位于implements关键字之前

    学习中,博客都是自己学习用的笔记,持续更新改正。。。
  • 相关阅读:
    live 555 freebsd 或centos 7.4 实现代理视频直播服务
    [教学] Log.d 日志调试查看(所有平台)
    [示例] 使用 TStopwatch 计时
    [安裝] Ubuntu Server 初试
    [改善] dcef3 for Firemonkey 浏览器控件,拉动窗体大小会闪烁的问题
    [示例] Drag And Drop for FireMonkey (Win & macOS)
    [原创] 改善 Firemonkey Canvas 几何绘图质量问题(移动平台)
    [示例] Firemonkey 画出 1 点像素的线
    [修正] Firemonkey TFrame 存档后,下次载入某些事件连结会消失(但源码还在)
    [问答] Firemonkey 控件继承后无法显示(空白)
  • 原文地址:https://www.cnblogs.com/Tunan-Ki/p/11668646.html
Copyright © 2020-2023  润新知