14 面对对象(多态;抽象类;接口)

  • 回顾
package org.westos.demo;

public final class 回顾 extends Object{
    public static void main(String[] args) {
        /*
        *  继承:将多个子类的共性内容,向上抽象到父类中,以实现代码的复用性和维护性,
        *  继承的弊端:让类跟类产生了关系,增加了耦合性。
        *  继承注意的事项:
        *  1.Java中只支持单继承,但是支持多层继承
        *  2.父类私有的成员,子类不能继承
        *  3,构造方法不参与继承
        *  4.不要为了继承而继承。
        *
        *  Object 类是所有类的顶层父类,所有类都是直接或间接继承自他
        *
        *  方法重写,:因为所有的子类,他继承了父类的功能,那如果说,某个子类,对继承下来的功能实现不满意。
        *  子类如果不满意父类的功能,就可以覆盖,覆盖之后,就以子类覆盖过后的为准
        *  重写的注意事项:
        *  父类的私有功能不能重写
        *  静态方法不参与重写
        *  重写时子类方法的权限修饰符,要比父类的高,或者一样
        *  父类final修饰的方法,也不能重写
        *  我们在初始化子类时,要先初始父类的数据 super()
        *  super 代表父类空间的一个标识
        *  this 代表本类的一个引用,谁调用方法,方法中的this就代表谁
        *
        *  final 修饰 变量,成员方法,类
        * */
    }
}
class  A extends  Object{
    //Object 类是所有类的顶层父类,所有类都是直接或间接继承自他
}
class  B extends A{
}

多态(动态绑定机制)

多态的概述

  • 多态概述
    某一个事物,在不同时刻表现出来的不同状态。
    举例: Cat c=new Cat();
    Animal a=new Cat();
    猫可以是猫的类型。猫 m = new 猫();
    同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫();
  • 多态前提
    a:要有继承关系。
    b:要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
    c:要有父类引用指向子类对象。
    父 f = new 子();

package org.westos.demo;
public class Animal {
    public void eat() {
        System.out.println("吃饭");
    }
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫爱吃鱼");
    }
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}

//------------------------------------------------------------------------
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("看门");
    }
}
package org.westos.demo;
public class MyDemo {
    public static void main(String[] args) {
        /*
        * 多态:指的是一种事物在不同时刻,所表现出的不同的状态
        * 猫 是一只猫
        * 猫 是一种动物
        * 用这两种状态描述猫都没有问题
        * Cat cat=new Cat(); 用Cat接受
        * Animal an=new Cat(); 用Animal接受
        * 多态的前提:
        * 1.要有继承关系,如果没有继承关系,那么多态就无从谈起。
        * 2.要有方法重写,如果没有方法重写,语法上不报错,但是多态就没有意义
        * 3.父类引用指向子类对象。
        * */
         //之前的方式
        Cat cat = new Cat();
        cat.eat();//猫爱吃鱼
        cat.catchMouse();//抓老鼠
        System.out.println("------------------------");
        //多态的方式
       Animal an= new Cat();//用Animal接受Cat
       an.eat();//猫爱吃鱼
       //如果采用了多态的这种方式,子类重写了父类的方法,那么我在用父类引用调用方法时,会以子类重写过后的为准
        System.out.println("-------------------");
        Dog dog = new Dog();//以前的
        dog.eat();//狗吃骨头
        dog.lookDoor();//看门
        System.out.println("--------------------");
        Animal an2=new Dog();//多态的
        an2.eat();//狗吃骨头
    }
}

package org.westos.demo;

public class Animal {
    public void eat() {
        System.out.println("吃饭");
    }
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    };
}
//------------------------------------------------------------------------
public class Dog extends Animal{
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
//------------------------------------------------------------------------
public class Tiger extends Animal{
    @Override
    public void eat() {
        System.out.println("老虎吃鸡");
    }
}
//------------------------------------------------------------------------
public class Fox extends Animal{
    @Override
    public void eat() {
        System.out.println("狐狸吃松鼠");
    }
}
package org.westos.demo;
public class MyUtils { //把MyUtils作为一个工具类
    private MyUtils() {  //私有化构造 工具类一般让用户直接调
    }
    public static void setAnimal(Animal an) { //改成(Animal an)父类类型Animal 就可以接受所有的之类的类型
        an.eat();
     }
  /* public static void setAnimal(Dog dog) {
        dog.eat();
     }
    public static void setAnimal(Cat cat) {
        cat.eat();
    }
    public static void setAnimal(Tiger tiger) {
        tiger.eat();
    }   */
}
package org.westos.demo;
public class MyDemo {
    public static void main(String[] args) {
        /*
        *  多态的优点:
        *  1.提高代码的维护性 由继承来保证
        *  2.多态提高了代码的扩展性
        *
        *  多态的不足:不能直接调用子类特有的功能
        * */
        Dog dog = new Dog();
        MyUtils.setAnimal(dog);// Animal an=new Dog(),之后an.eat()调用的是子类Dog重写后的

        Cat cat = new Cat();
        MyUtils.setAnimal(cat);

        Tiger tiger = new Tiger();
        MyUtils.setAnimal(tiger);

        Fox fox = new Fox();
        MyUtils.setAnimal(fox);
    }
  /* public static void setAnimal(Animal an) {
        an.eat();
    } */
}

多态的成员访问特点

  • 多态中的成员访问特点
    a:成员变量
    编译看左边,运行看左边。
    b:构造方法
    创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
    c:成员方法
    编译看左边,运行看右边。
    d:静态方法
    编译看左边,运行看左边。
    (静态和类相关,算不上重写,所以,访问还是左边的)
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //Zi zi = new Zi();
        //System.out.println(zi.num);//100
        
        //多态
        
        //多态的形式去访问成员变量,访问的还是父类的成员变量
        //多态访问成员变量:编译看左边,运行看左边。
        Fu fu=new Zi();
        System.out.println(fu.num);//10 //用父类引用调父类变量
        
        
        //多态的形式去调用方法时,编译看左边,运行看右边 
        //编译看左边即父类里面有没有这个方法 运行看右边即子类有没有重写过
        fu.show();//方法重写后 调的是子类重写后的方法  如果没有重写就调父类的

        //调用静态方法,运行的是父类的静态方法 //静态方法不算重写
        fu.test();       
    }
}
//------------------------------------------------------------------------
class Fu{
    int num=10;
    public Fu() {
        System.out.println("父类构造执行了");
    }
    public void show(){
        System.out.println("fu show");
    }
    public static  void test() {
        System.out.println("fu test");
    }
}
//------------------------------------------------------------------------
class Zi extends Fu{
    int num=100;
    public Zi() {
        System.out.println("子类构造执行了");
    }
    @Override
    public void show() {
        System.out.println("zi show");
    }
    public static void test() {
        System.out.println("zi test");
    }
}

多态的好处和弊端

  • 多态的好处
    a:提高了代码的维护性(继承保证)
    b:提高了代码的扩展性(由多态保证)
  • 多态的弊端
    不能直接调用子类特有的功能

向上转型和向下转型

  • 通过多态的弊端引出问题
    不能使用子类特有的功能
  • 解决问题
    把父类的引用强制转换为子类的引用。(向下转型)
package org.westos.demo;

public class Animal {
    public void eat(){
        System.out.println("吃饭");
    }
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catcheMouse(){
        System.out.println("猫抓老鼠");
    }
}
//------------------------------------------------------------------------
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("狗看门");
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat();
        cat.catcheMouse();

        System.out.println("----------------------------");
        //多态的形式
        Animal an = new Cat(); //多态就是向上转型 //将子类类型Cat用父类an输
        an.eat();

        //多态的弊端,不能访问子类特有的功能
       // an.catcheMouse(); 会报错 这是多态的弊端 父类引用an调不到子类Cat特有的功能
        Cat cat= (Cat) an;  //将父引用an转成所指的子类型Cat 再用cat去调
     //向下转型 将父引用转成他所指向的那个子类型      
        cat.catcheMouse();

        System.out.println("------------------");
        Dog dog = new Dog();
        dog.eat();
        dog.lookDoor();

        System.out.println("----------------------------");
        Animal an2= new Dog();
        an2.eat();

       Dog d= (Dog) an2; //向下转型
       d.lookDoor();
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        Animal an = new Dog();
        an.eat();
       // an.lookDoor(); //Dog特有方法不能直接用an来调 需要向下转型
        Dog d= (Dog) an;
        d.lookDoor();

       // an=new Cat();
        Cat cat = (Cat) an;//在这一行会报错:ClassCastException 类型转换异常
//Animal an = new Dog():new了一个Dog对象 在栈内存中存在引用an an指向这个Dog对象
//可以Dog d= (Dog) an将an转成Dog(向下转型就是将父类型转向它指向的那个类型);现在an指向Dog,不能把Dog强转成Cat
        //如果 Cat cat = (Cat) an 前面加一行" an=new Cat() " 就不报错,将an指向Cat,再将an转型为Cat
        cat.catcheMouse();
    }
}

package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        /*
         * 听说孔子爹JavaSE讲的很好,张三慕名前来,把孔子爹请到家里去给他讲课去了
         * 那么这个时候,李四也来到孔子家里,请孔子爹讲JavaSE 孔子一看学员来了,孔子爹又不在家,
         * 孔子又不想失去这个学员,孔子经过乔装打扮,装成他爹的样子,给李四讲课,他只会讲论语,
         * 讲完之后,把李四打发走了,孔子想玩游戏了,卸下这套装扮,去开心的玩游戏去了
         * */
        孔子爹 k爹 = new 孔子(); //多态:向上转型 //孔子要装成孔子爹的模样 即向上转型
        System.out.println(k爹.age);  //外在表现 age 60
        k爹.teache();

        孔子 k = (孔子) k爹; //向下转型 //孔子想玩游戏了,卸下这套装扮 即向下转型
        System.out.println(k.age);  //外在表现 age 30
        k.playGame(); //向下转型后就可以  调用自己特有的方法
    }
}
//------------------------------------------------------------------------
class 孔子爹 {
    int age = 60;

    public void teache() {
        System.out.println("讲授JavaSE");
    }
}
//------------------------------------------------------------------------
class 孔子 extends 孔子爹 {
    int age = 30;

    public void teache() {
        System.out.println("讲授论语");
    }

    public void playGame() {
        System.out.println("玩游戏");
    }
}

多态内存图

  • 画图演示: 多态的内存图解
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {

        Father fu = new Son();
        System.out.println(fu.num);//100
        fu.show();//zi Show      //当子类中重写了父类方法后 用多态的形式去调 还是以子类重写过后的为准

        Son son = (Son) fu;
        System.out.println(son.num);//19
        son.method();//子类特有的方法
    }
}
//------------------------------------------------------------------------
class Father {
    int num = 100;
    public void show() {
        System.out.println("fu show");
    }
}
//------------------------------------------------------------------------
class Son extends Father {
    int num = 19;
    @Override
    public void show() {
        System.out.println("zi Show");
    }
    public void method() {
        System.out.println("子类特有的方法");
    }
}

在这里插入图片描述


  • 其他举例
    在这里插入图片描述

猫狗案例多态版

案例演示: 猫狗案例多态版

package org.westos.demo;

public class Animal {
    public String name;
    public int age;
    public void eat(){
        System.out.println("吃饭");
    };
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}
//------------------------------------------------------------------------
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("狗看门");
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Animal an=cat;
        an.name="汤姆";
        an.age=2;
        System.out.println(an.name+"==="+an.age);
        an.eat();
        Cat cat1= (Cat) an;
        cat1.catchMouse();
        System.out.println("----------------------------");
        an=new Dog();
        an.name="旺财";
        an.age=10;
        System.out.println(an.name + "===" + an.age);
        an.eat();
        Dog dog= (Dog) an;
        dog.lookDoor();
    }
}

多态中的题目分析题

看下面程序是否有问题,如果没有,说出结果

class A {
    public void show() {
        show2();
    }

    public void show2() {
        System.out.println("我");
    }
}

class B extends A {
    public void show2() {
        System.out.println("爱");
    }
}

class C extends B {
    public void show() {
        super.show();
    }

    public void show2() {
        System.out.println("你");
    }
}

public class DuoTaiTest {
    public static void main(String[] args) {
        A a = new B();
        a.show();  //爱

        B b = new C();
        b.show();  //你
    }
}

在这里插入图片描述在这里插入图片描述

抽象类

抽象类的概述

  • 抽象类概述
    回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
    为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。
    所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
    同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
    在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
  • 抽象类特点
    a:抽象类和抽象方法必须用abstract关键字修饰
    抽象类格式: abstract class 类名 {}
    抽象方法格式: public abstract void eat();
    b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
    c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
    用于子类访问父类数据时的初始化
    d:抽象类不能直接实例化那么,抽象类如何实例化呢?
    按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    e:抽象类的子类
    要么是抽象类
    要么重写抽象类中的所有抽象方法

package org.westos.demo;

public abstract class Animal {
    //abstract 抽象的,可以修饰方法,修饰类
    //抽象方法:没有方法体的方法 
    //当你一个类中,有了抽象,此类也必须为抽象类
    //一个抽象类中可以没有抽象方法,但是一个类中有了抽象方法,此类必须为抽象类
//(肯定知道子类要吃饭睡觉 至于怎么吃怎么睡就是子类的事情  抽象类中的抽象方法强制子类必须重写)
//(父类没有必要给出这类功能的具体实现 等子类继承后 你想怎么吃就怎么吃 想怎么睡就怎么睡 子类自己给出具体功能的重写)
    public Animal() {
       System.out.println("Animal 的构造方法");
    }
    public abstract void eat();
    public abstract void sleep();
    public void show(){
        System.out.println("fu show");
     }
}
//------------------------------------------------------------------------
public class Dog extends Animal {
    public Dog() {
       System.out.println("Dog 的构造方法");
    }
//当一个类,继承了一个抽象类,那么这个抽象类中的所有抽象方法,子类必须重写
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗趴着睡觉");
    }
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //1.抽象类,不能直接实例化
        //2.我们可以采用多态的形式,间接实例化
        Animal an = new Cat(); //采用多态的形式去new的时候 肯定要初始化父类 父类的构造方法先执行 
        //(抽象类中构造方法:用于子类访问父类数据时的初始化)
        an.eat();
        an.sleep();
    
        an = new Dog();
        an.eat();
        an.sleep();
    }
}

package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
    }
}
//------------------------------------------------------------------------
abstract  class Fu{
    public abstract void test();
}
//------------------------------------------------------------------------
abstract class Zi extends Fu{ //父类是抽象类 子类要么把自己变成抽象类 要么重写父类中的所有抽象方法
  public abstract  void aa();
}
//------------------------------------------------------------------------
class C extends Zi{ //爸爸Zi和爷爷Fu里面的抽象方法都要继承 
    @Override
    public void test() {
    }
    @Override
    public void aa() {
    }
}

抽象类的成员特点

  • 抽象类的成员特点
    a:成员变量:既可以是变量,也可以是常量。
    b:构造方法:有。
    用于子类访问父类数据的初始化。
    c:成员方法:既可以是抽象的,也可以是非抽象的。
  • 案例演示
    抽象类的成员特点
  • 抽象类的成员方法特性:
    a:抽象方法 强制要求子类做的事情。
    b:非抽象方法 子类继承的事情,提高代码复用性。
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //抽象类中,成员变量的特点 抽象类中既可以定义变量,也可以定义常量
        //抽象类中有构造方法,作用:在创建子类对象时,对父类数据进行初始化
        //抽象类中,可以有抽象方法,也可以有非抽象方法
        //抽象方法,强制子类必须重写
        //非抽象方法,是想让子类继承下去用
    }
}
abstract class AA{
    int num=100;

    public final int a = 10;

    public void aa(){};
    public abstract void bb();
}

抽象类的案例

  • 抽象类练习猫狗案例
    案例演示
    具体事物:猫,狗
    共性:姓名,年龄,吃饭
package org.westos.demo;

public abstract class Aniaml {
    public String name;
    public int age;
    public abstract void eat();
}
//------------------------------------------------------------------------
public class Cat extends Aniaml {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}
//------------------------------------------------------------------------
public class Dog extends Aniaml{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("狗看门");
    }
}
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        //案例演示
        //具体事物:猫,狗
        //共性:姓名,年龄,吃饭
        Aniaml an = new Cat();
        an.name="汤姆";
        an.age=2;
        System.out.println(an.name+"==="+an.age);
        an.eat();
        ((Cat) an).catchMouse();

        an=new Dog();
        an.name="旺财";
        an.age=9;
        System.out.println(an.name+"=="+an.age);
        an.eat();
        ((Dog) an).lookDoor();
    }
}
  • 抽象类练习员工案例
    A:案例演示
    假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
    经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。
    然后定义工作的方法.
    请使用继承的思想设计出员工类和经理类。
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        Person p=new Employee();
        p.name="张三";
        p.id=1;
        p.sal=3000;
        System.out.println(p.name+"==="+p.id+"==="+p.sal);
        p.work();

        p=new Manager();
        p.name="李四";
        p.id=2;
        p.sal=50000;
        Manager m= (Manager) p;//向下转型
        m.bonus=1000;
        p.work();
        System.out.println(p.name+"==="+p.id+"==="+p.sal+"=="+m.bonus);

         //一个类如果没有抽象方法,可不可以定义为抽象类 ? 如果可以,有什么意义 ?
         //可以,外界就不能创建该类的对象
        
       // abstract 不能和哪些关键字共存:
        // private 矛盾(私有的方法都不能被继承 何谈重写)  
        // final 矛盾(final不让重写 abstract强制重写)  
        // static 没有意义(静态的抽象方法 不能共存 没有意义)
    }
}
//------------------------------------------------------------------------
abstract class Person {
    int id;
    String name;
    double sal;

    public abstract void work(); //都要工作 但是工作的内容不一样 所以将工作变为抽象方法
    //public  abstract void show();
}
//------------------------------------------------------------------------
class Employee extends Person {

    @Override
    public void work() {
        System.out.println("做一些一线的工作");
    }
}
//------------------------------------------------------------------------
class Manager extends Person {
    double bonus;

    @Override
    public void work() {
        System.out.println("做管理的工作");
    }
}
  • 抽象类中的面试题
    A:面试题1
    一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
    答案: 可以 . 不能创建对象.
    B:面试题2
    abstract不能和哪些关键字共存?
    private 冲突
    final 冲突
    static 不能共存 无意义

接口

接口的概述

  • 接口概述
    继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
    但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
    而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。
    所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
    所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
  • 接口特点
    a:接口用关键字interface表示 格式: interface 接口名 {}
    b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
    c:接口不能实例化
    那么,接口如何实例化呢?
    按照多态的方式来实例化。
    d:接口的子类
    a:可以是抽象类。但是意义不大。
    b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

package org.westos.demo;

public abstract class Animal {
    public abstract void eat();
}
//------------------------------------------------------------------------
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
//------------------------------------------------------------------------
public class Dog extends Animal implements FireInterface{ 
                             //“implements FireInterface” 实现钻火圈这个功能 把里面的方法重写进这个类里
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void fire() {   
//这样定义 new的所有狗都会钻火圈 而且钻火圈这个功能和狗没什么关系 
//所以这类功能应定义到一个接口里去 接口里定义一些额外扩展的功能 而不是与类相关的功能 与类相关的功能肯定是定义在类里的
        System.out.println("狗经过后天的学习,学会了钻火圈");
    }
}
//------------------------------------------------------------------------
public interface FireInterface { //定义一个接口
    //接口中定义的是抽象方法
    public abstract void fire();
}
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        //接口:与类同级别,接口主要用来定义一些扩展额外的功能,那哪些事物,想要具备这些功能,可以去实现这个接口
        //如何定义一个接口,使用关键字 interface
        Animal an = new Cat();
        an.eat();

        Dog dog = new Dog();
        an = dog;
        an.eat();
        FireInterface fireInterface = dog;
        fireInterface.fire();
        //接口不能实例化 按照多态方式实例化(不能去new接口的对象)
    }
}

package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
    }
}
//------------------------------------------------------------------------
interface  AA{
    public abstract void aa();
    public abstract void show();

}
//------------------------------------------------------------------------
class BB implements AA{ // implements 实现关系 :子类实现接口
//你一个普通的类,要实现一个接口,那么得全部重写接口中所有的抽象方法

    @Override
    public void aa() {
    }

    @Override
    public void show() {
    }
}

接口的成员特点

  • 接口成员特点
    • 成员变量;只能是常量,并且是静态的。
      默认修饰符:public static final
      建议:自己手动给出。
    • 构造方法:接口没有构造方法。
    • 成员方法:只能是抽象方法。
      默认修饰符:public abstract
      建议:自己手动给出。
package org.westos.demo;

public interface MyInterface {  //接口中语法特点:
    public static final int NUM = 100; //接口中没有变量 全是 公共的静态常量 
    //int NUM = 100 前面有默认的缺省的修饰符 public static final 不写也有
    int B=10;//公共的静态常量 //前面有默认的修饰符  public static final
    
    //接口中没有非抽象方法,全是抽象方法
    public abstract void aa();
    void bb(); //前面有默认的修饰符 public abstract //没写 默认肯定是抽象方法
    //public void hehe(){}; 报错,接口不能有非抽象方法
    //接口中没有构造方法
}
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        int num = MyInterface.NUM;//接口名可以直接调用 公共静态常量用接口名直接调用就行 不要new也不允许new
        System.out.println(num);
    }
}

类与类,类与接口,接口与接口的关系

  • 类与类,类与接口,接口与接口的关系
    a:类与类:
    继承关系,只能单继承,可以多层继承。
    b:类与接口:
    实现关系,可以单实现,也可以多实现。
    并且还可以在继承一个类的同时实现多个接口。
    c:接口与接口:
    继承关系,可以单继承,也可以多继承。
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        //类跟类的关系
        //类跟类的关系,是继承关系 extends,但只能是单继承

        //类跟接口的关系
        //类跟接口的关系,是实现关系,implments 实现可以多实现,一个类可以实现多个接口
        //我们一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口
        
        //接口跟接口的关系
        //接口跟接口有继承关系,而且支持多继承
    }
}
abstract class Fu{
    public abstract  void fu();
}
//------------------------------------------------------------------------
interface A{
    void a();
    void aa();
}
//------------------------------------------------------------------------
interface  B{
    void b();
    void bb();
}
//------------------------------------------------------------------------
interface  C{
    void c();
}
//------------------------------------------------------------------------
class MyClass extends Fu implements A,B,C{ //一个类可以实现多个接口 每个接口的抽象方法必须全部实现
    //一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口  //也必须实现父类里的抽象方法

    @Override
    public void a() {
    }
    @Override
    public void aa() {
        //空实现   //里面没写具体逻辑
    }
    @Override
    public void b() {
    }
    @Override
    public void bb() {
    }
    @Override
    public void c() {
    }
    @Override
    public void fu() {
    }
}
//------------------------------------------------------------------------
interface AA{
    void a();
    void aa();
}
//------------------------------------------------------------------------
interface  BB{
    void b();
    void bb();
}
//------------------------------------------------------------------------
interface CC extends AA,BB{ //接口跟接口有继承关系,而且支持多继承
    void cc();
}
//------------------------------------------------------------------------
class DD implements CC{

    @Override
    public void a() {
    }
    @Override
    public void aa() {
    }
    @Override
    public void b() {
    }
    @Override
    public void bb() {
    }
    @Override
    public void cc() {
    }
}

抽象类与接口的区别

  • 成员区别
    抽象类:
    成员变量:可以变量,也可以常量
    构造方法:有
    成员方法:可以抽象,也可以非抽象
    接口:
    成员变量:只可以常量
    成员方法:只可以抽象
  • 关系区别
    类与类
    继承,单继承
    类与接口
    实现,单实现,多实现
    接口与接口
    继承,单继承,多继承
  • 设计理念区别
    抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
    接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
package org.westos.demo;

public interface  AA{
    void test();
    public default void aa(){
        System.out.println("aa方法的具体功能实现");
    }
}
//------------------------------------------------------------------------
interface BB{
    //JDK1.8之后,可以有用 default修饰的方法 //default:接口默认方法实现
    default void bb() {
        System.out.println("bb方法的具体功能实现");
    }
}
//------------------------------------------------------------------------
class EE implements AA,BB{
    @Override
    public void test() {
        System.out.println("test");
    }
}
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
//抽象类跟接口的区别—————
//成员变量的区别:抽象类中可以定义成员变量,也可以定义常量 接口中只能是公共的静态常量,使用接口名可以直接调用
//构造方法的区别:抽象类中有构造方法,接口中没有构造方法
//成员方法的区别:抽象类中可以有抽象方法,也可以有非抽象方法,接口中只能是抽象方法(JDK1.7之前)
//设计理念的区别,抽象类体现是一种is a的关系(继承共性 什么是什么),接口 like a 的关系(继承扩展什么像什么)

//抽象类跟接口的共同点,抽象类和接口,不能直接实例化
//JDK1.8之后,接口中可以定义默认方法,默认方法可以有方法体

//C类 A类 B类:C类想继承A类和B类中的方法 但是由于单继承 类每次只能继承一个类 不能多继承几个类 
//C类 A接口 B接口:C类可以同时实现A接口和B接口中的所有方法 弥补了单继承的不足
//类每次只能单继承一个类 不能多继承几个类 为了解决这个问题 出现了接口中写具体实现方法以及可以同时实现多个接口
/* JDK1.7之前A接口和B接口里面定义的是抽象方法 方法在接口中没有做实现 实现的东西是自己写的 自己把它实现了 
但是现在我们不想自己去实现 就想拿来现成的就直接用 
所以JDK1.8之后让接口中出现一种方法 这种方法有它具体的功能实现 
即在接口中把方法实现写好之后 类可以随意继承多个接口里面的方法 可以弥补单继承的不足 */
        EE ee = new EE(); //接口中只能是公共的静态常量,使用接口名可以直接调用
        ee.aa();  //ee可以用第一个接口中的 aa方法
        ee.bb();  //ee可以用第二个接口中的 bb方法
        //弥补了类的单继承的不足
    }
}
//abstract class A{ //抽象类中可以定义成员变量,也可以定义常量
//    int num=100;
//    public static final int A=10;
//}

接口的案例

猫狗案例加入跳高功能分析及其代码实现
A:案例演示
动物类:姓名,年龄,吃饭,睡觉。
动物培训接口:跳高
猫继承动物类
狗继承动物类
部分猫继承猫类并实现跳高接口
部分狗继承狗类并实现跳高接口

通过抽象类测试基本功能。
通过接口测试扩展功能。

package org.westos.demo;
public abstract class Animal {
    public String name;
    public int age;
    public abstract void eat();//定义成抽象的 强制子类去重写
    public abstract void sleep();
}
//------------------------------------------------------------------------
package org.westos.demo;
public interface JumpInterface {
    void jump();
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Tom extends Cat implements JumpInterface{
    @Override
    public void eat() {
        System.out.println("汤姆爱吃杰瑞");
    }

    @Override
    public void sleep() {
        System.out.println("汤姆不睡觉");
    }

    @Override
    public void jump() {
        System.out.println("tom经过不断的学习,学会了跳高");
    }


    public void tom() {
        System.out.println("tom特有的功能");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;
public class BigFaceCat extends Cat{
    @Override
    public void eat() {
        System.out.println("大脸猫爱吃蓝皮鼠");
    }

    @Override
    public void sleep() {
        System.out.println("大脸猫天天睡觉");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;
public class WaiCaiDog extends Dog{
    @Override
    public void eat() {
        System.out.println("旺财爱吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("旺财睡觉打呼噜");
    }

    public void lookDoor(){
        System.out.println("看门");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;
public class GaoFeiDog extends Dog implements JumpInterface{
    @Override
    public void eat() {
        System.out.println("高飞狗吃饼干");
    }

    @Override
    public void sleep() {
        System.out.println("高飞狗睡觉睡不醒");
    }

    @Override
    public void jump() {
        System.out.println("高菲学会了跳高");
    }
}
//------------------------------------------------------------------------
package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        //A:
        //案例演示
        //动物类:  姓名,年龄,吃饭,睡觉。
        //动物培训接口:跳高
        //猫继承动物类
        //狗继承动物类
        //部分猫继承猫类 并实现跳高接口
        //部分狗继承狗类 并实现跳高接口
        //
        //通过抽象类 测试 基本功能。
        //通过接口 测试 扩展功能。
        //只测试猫,狗的测试留给学生自己练习
        Tom tom = new Tom();
        Cat cat=tom;
        cat.name="Tom";
        cat.age=2;
        System.out.println(cat.name+"==="+cat.age);
        cat.eat();
        cat.sleep();

        ((Tom) cat).tom(); //向下转型 //可以调tom特有功能
        //多态//父接口引用,执行子类对象
        JumpInterface jumpInterface=tom;
        jumpInterface.jump();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值