java基础(7)(接口、接口成员访问、接口与抽象类的区别、单继承多实现、多态、多态中的转型、instanceof等)

接口
什么是接口?

    接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。 接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。 另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口的定义格式

public interface 接口名 {}

注意:接口不能创建对象,必须有实现类才能使用,类实现接口用implements表示;接口的实现类必须重写接口中的所有抽象方法,要么该类是一个抽象类。
接口成员的特点

    成员变量:只能是常量,默认修饰符:public static final

    成员方法:只能是抽象方法,默认修饰符:public abstract

    构造方法:没有构造方法,因为接口主要是扩展功能的,而没有具体存在

    //接口
 

    public interface Inter {
        public int num = 10;
        public final int num2 = 20;
        //接口中无构造方法
        //public Inter(){}
        //接口中无具体方法
        //public void show(){}
        public abstract void method();
        //抽象方法默认为 public abstract
        void show();
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 16:45
     */
    public class InterImpl implements Inter {//接口实现类
        public InterImpl(){
            super();
        }
        @Override
        public void method() {
            System.out.println("method");
        }
     
        @Override
        public void show() {
            System.out.println("show");
        }
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 16:46
     */
    public class test {
        public static void main(String[] args) {//测试类
            Inter inter = new InterImpl();
            //inter.num = 20;
            System.out.println(inter.num);
            //inter.num2 = 40;
            System.out.println(inter.num2);
            System.out.println(Inter.num);
        }
    }

接口与类的关系

    类与类的关系:继承关系,只能是单继承,但是可以多层继承

    类与接口的关系:实现关系,可以单实现,也可以继承一个类同时实现多个接口

    接口与接口的关系:继承关系,可以单继承,也可以多继承

抽象类与接口的区别

    成员区别

    抽象类:有变量、常量;构造方法;抽象方法;非抽象方法

    接口:常量;抽象方法

    关系区别

    类与类:继承,单继承

    类与接口:实现,可以但实现,也可以多实现

    接口与接口:继承,单继承,多继承

    设计理念区别

    抽象类:为了继承而来,让子类强制重写父类的抽象方法

    接口:对行为抽象,主要是行为

继承父类并实现多个接口

实现格式:

    class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {     
        // 重写接口中抽象方法【必须】
        // 重写接口中默认方法【不重名时可选】
     }

代码演示:

    //接口A
    public interface A {
        public abstract void showA();
        void show();
    }
    //接口B
    public interface B {
        void showB();
        void show();
    }
    //父类
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 16:53
     */
    public class Fu {
    }
    //实现类
     
    /**
     * @Describe 继承父类实现多个接口
     * @Author Double LiFly
     * @date 2021/4/8 16:53
     */
    public class C extends Fu implements A,B {
        /**
         * 接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次即可!
         * 如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法。
         */
        @Override
        public void showA() {
            System.out.println("showA");
        }
     
        @Override
        public void showB() {
            System.out.println("showB");
        }
     
        @Override
        public void show() {
            System.out.println("Show");
        }
    }

接口之间的多继承

代码演示:

    //接口A
    public interface A {
        public void methodA();
    }
    //接口B
    public interface B {
        void methodB();
    }
    //接口C
    /**
     * 接口多继承之后,如果想使用,我们还必须定义实现类,才能使用
     */
    public interface C extends A,B {
        void methodC();
    }

接口小结

    接口中只有常量和抽象方法

    接口是没有静态代码块和构造方法的

    一个类的直接父类是唯一的,但是一个类可以同时实现多个接口,单继承多实现

    如果实现类所实现的多个接口中,存在重复的抽象方法,那么只需要重写覆盖一次就好

    如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么这个类就必须是一个抽象类

接口案例

对猫和狗进行训练,他们就可以跳高了,这里加入跳高功能。

请采用抽象类和接口来实现猫狗案例,并在测试类中进行测试

代码实现:

    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:00
     */
    public abstract class Animal {//抽象动物类
        private String name;
        private int age;
        public Animal(){}
        public Animal(String name,int age){
            this.name=name;
            this.age=age;
        }
     
        public int getAge() {
            return age;
        }
     
        public void setAge(int age) {
            this.age = age;
        }
     
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        public abstract void eat();
    }
    public interface Jumpping {//接口
        public abstract void jump();
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:04
     */
    public class Cat extends Animal implements Jumpping {//实现类
        public Cat(){}
        public Cat(String name,int age){
            super(name, age);
        }
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
     
        @Override
        public void jump() {
            System.out.println("猫可以跳高了");
        }
    }
    //测试类
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:05
     */
    public class test {
        public static void main(String[] args) {
            Cat cat = new Cat();
            cat.setName("加菲");
            cat.setAge(3);
            System.out.println(cat.getName()+","+cat.getAge());
            cat.eat();
            cat.jump();
        }
    }

多态

多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作
优点

    1. 消除类型之间的耦合关系

    2. 可替换性

    3. 可扩充性

    4. 接口性

    5. 灵活性

    6. 简化性

多态存在的三个必要条件

继承 重写 父类引用指向子类对象:Parent p = new Child(); 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。 多态的好处: 可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
多态格式

普通类多态的格式

    父类 对象 = new 子类();

抽象类多态的格式

    抽象类 对象名 = new 抽象类子类();

接口多态的格式

    接口 对象名 = new 接口实现类();

多态中的成员访问特点

成员变量

    编译看父类,运行看父类

成员方法

    编译看父类,运行看子类

猫狗案例:

    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:18
     */
    public abstract class Animal {
        public abstract void eat();
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:18
     */
    public class Cat extends Animal {
        @Override
        public void eat() {
            System.out.println("吃鱼");
        }
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:19
     */
    public class Dog extends Animal {
        @Override
        public void eat() {
            System.out.println("吃骨头");
        }
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:19
     */
    public class Test {
        public static void main(String[] args) {
            //多态形式创建对象
            Cat cat = new Cat();
            Dog dog = new Dog();
            showCat(cat);
            shwoDog(dog);
              /*
                以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代        
                而执行效果一致
            */
            showAnimal(cat);
            showAnimal(dog);
        }
        public static void showCat(Cat cat){
            cat.eat();
        }
        public static void shwoDog(Dog dog){
            dog.eat();
        }
        public static void showAnimal(Animal animal){
            animal.eat();
        }
    }

多态中的转型

为什么需要转型?

    当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

向上转型

多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的

使用格式:

    父类类型 变量名 = new 子类类型();

    例如:Father father = new son();

向下转型

父类类型向子类类型向下转换的过程,这个过程是强制的。一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型

使用格式:

    子类类型 变量名 = (子类类型)父类变量名;

    例如:Cat cat = (Cat)animal;

instanceof使用格式

    变量名 instanceof 数据类型

    如果变量属于给数据类型,返回true

    如果变量不属于该数据类型,返回false

综合案例

    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:26
     */
    public abstract class Animal {
        abstract void eat();
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:26
     */
    public class Cat extends Animal {
        @Override
        void eat() {
            System.out.println("吃鱼");
        }
        public void catchMouse(){
            System.out.println("抓老鼠");
        }
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:27
     */
    public class Dog extends Animal {
        @Override
        void eat() {
            System.out.println("吃骨头");
        }
        public void watchHouse(){
            System.out.println("看家");
        }
    }
    /**
     * @Describe
     * @Author Double LiFly
     * @date 2021/4/8 17:28
     */
    public class Test {
        public static void main(String[] args) {
            //向上转型
            Animal animal = new Cat();
            animal.eat();//调用的是Cat的eat
     
            //向下转型
            Cat cat = (Cat) animal;//调用的是Cat的catchMouse
            cat.catchMouse();
     
            //Dog dog = (Dog) animal;
           // dog.watchHouse();//报错java.lang.ClassCastException转型异常
            //Java提供了instanceof关键字,给引用变量做类型的校验
            System.out.println("~~~~~~~~~~~");
            if (animal instanceof Cat){
                Cat cat1 = (Cat) animal;
                cat1.catchMouse();
            }else if (animal instanceof Dog){
                Dog dog1 = (Dog) animal;
                dog1.watchHouse();
            }
        }
    }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值