10.java基础-抽象和接口

抽象

抽象类概述

回想前面我们的猫狗案例,提取出了一个动物类。
并且我们在前面也创建过了动物对象,其实这是不对的。
为什么呢?因为我说动物,你知道我说的是什么动物吗?
只有看到了具体的动物,你才知道,这是什么动物。 
所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有猫、狗、马才是具体的动物。
同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。

抽象类特点

A:抽象类和抽象方法必须用abstract关键字修饰
        B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
        C:抽象类不能实例化
            因为它不是具体的。
            抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
            用于子类访问父类数据的初始化
        D:抽象的子类
            a:如果不想重写抽象方法,该子类是一个抽象类。
            b:重写所有的抽象方法,这个时候子类是一个具体的类。
            
        抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
            Animal a = new Cat();

抽象类不能实例化

抽象类的实例化要按照多态的方式,由具体的子类实例化。
其实这也是多态的一种,抽象类多态。抽象多态是继承多态的一种
抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法(具体类)

☆抽象类构造方法作用:父类数据的初始化

用于子类访问父类数据的初始化

//抽象类的声明格式
abstract class Animal {
    //抽象方法
    public abstract void eat();
    public Animal(){}
}

//子类是抽象类
abstract class Dog extends Animal {}

//子类是具体类,重写抽象方法
class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

class AbstractDemo {
    public static void main(String[] args) {
        //创建对象
        //Animal是抽象的; 无法实例化
        //Animal a = new Animal();
        //通过多态的方式
        Animal a = new Cat();
        a.eat();
    }
}

抽象类的成员特点

成员变量

可以是变量
也可以是常量

构造方法

有构造方法,但是不能实例化,那么,构造方法的作用是什么呢?
用于子类访问父类数据的初始化

成员方法

抽象类的成员方法特性:
A:抽象方法 强制要求子类做的事情。
B:非抽象方法 供子类继承,提高代码复用性。

abstract class Animal {
    public int num = 10;
    public final int num2 = 20;

    public Animal() {}
    
    public Animal(String name,int age){}
    
    public abstract void show();
    
    public void method() {
        System.out.println("method");
    }
}

class Dog extends Animal {
    public void show() {
        System.out.println("show Dog");
    }
}

class AbstractDemo2 {
    public static void main(String[] args) {
        //创建对象
        Animal a = new Dog();
        //a.num = 10;
        System.out.println(a.num);
        //a.num2 = 20;
        System.out.println(a.num2);
        System.out.println("--------------");
        a.show();
        a.method();
    }
}

没有抽象方法定义为抽象类:只能作为父类来被继承

这样做唯一的意义就是该类只能作为父类来被继承,限制该类不能被实例化。

abstract不能和哪些关键字共存

private:冲突

原因是abstract方法要被继承然后必须被子类重写。
但是子类只能继承父类所有非私有的成员(成员方法和成员变量)

final:冲突

原因是abstract方法要被继承然后必须被子类重写。
但是被final修饰的方法无法被子类重写

static:无意义

被static修饰的方法是属于类的方法,不存在重写一说

package netty.bytebuf;

abstract class Fu {
    //public abstract void show();
    //非法的修饰符组合: abstract和private
    //private abstract void show();
    
    //非法的修饰符组合
    //final abstract void show();    
    
    //非法的修饰符组合
    //static abstract void show();
    
    public static void method() {
        System.out.println("method");
    }
}

class Zi extends Fu {
    public void show() {}
}

class AbstractDemo3 {
    public static void main(String[] args) {
        Fu.method();
    }
}

接口:为了体现事物的扩展功能性

继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。

所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。

所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。

接口特点

接口用关键字interface表示

格式:interface 接口名 {}

类实现接口用implements表示

格式:class 类名 implements 接口名 {}

接口不能实例化

那么,接口如何实例化呢?
按照多态的方式,由具体的子类实例化。
其实这也是多态的一种,接口多态。
目前一共学了2种多态:继承多态、接口多态,其中抽象多态是继承多态的一种。

接口的子类

要么是抽象类,要么是接口,要么是接口的具体实现类。
接口的具体实现类必须重写接口中的所有抽象方法

由此可见:
A:具体类多态(几乎没有)
B:抽象类多态(常用)
C:接口多态(最常用)

//定义动物培训接口
interface AnimalTrain {
    public abstract void jump();
}

//抽象类实现接口
abstract class Dog implements AnimalTrain {
}

//接口继承接口
public interface DogTrain extends AnimalTrain {
}

//具体类实现接口
class Cat implements AnimalTrain {
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}

class InterfaceDemo {
    public static void main(String[] args) {
        //AnimalTrain是抽象的; 无法实例化
        //AnimalTrain at = new AnimalTrain();
        //at.jump();
        
        AnimalTrain at = new Cat();
        at.jump();
    }
}

接口成员特点

成员变量:默认修饰符public static fina即常量
构造方法:没有

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

成员方法默认修饰符 public abstract即抽象

只能是抽象方法

package netty.bytebuf;

/*
    接口成员特点
        成员变量;只能是常量,并且是静态的。
                默认修饰符:public static final
                建议:自己手动给出。
        构造方法:接口没有构造方法。
        成员方法:只能是抽象方法。
                默认修饰符:public abstract
                建议:自己手动给出。
        
    所有的类都默认继承自一个类:Object。
    类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
    接口的父类也是Object
*/
interface Inter {
    public int num = 10;
    public final int num2 = 20;
    public static final int num3 = 30;
    
    //错误:不允许在接口中
    //public Inter();
    
    //接口方法不能带有主体
    //public void show() {}

    //默认public abstract
    //abstract void show();

    //默认public abstract
    //public void show();

    //显式声明为 public abstract
    //public abstract void show();
}

//接口名+Impl这种格式是接口的实现类格式
/*
class InterImpl implements Inter {
    public InterImpl() {
        super();
    }
}
*/

class InterImpl extends Object implements Inter {
    public InterImpl() {
        super();
    }
    
    public void show() {}
}

//测试类
class InterfaceDemo2 {
    public static void main(String[] args) {
        //创建对象
        Inter i = new InterImpl();
        System.out.println(i.num);
        System.out.println(i.num2);
        //无法为最终变量num分配值
        //i.num = 100;
        //无法为最终变量num2分配值
        //i.num2 = 200;
        System.out.println(Inter.num);
        System.out.println(Inter.num2);
        System.out.println("--------------");
    }
}

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

类与类

继承关系,只能单继承,但是可以多层继承

类与接口

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

接口与接口

继承关系,可以单继承,也可以多继承

interface Father {
    public abstract void fatherShow();
}

interface Mother {
    public abstract void motherShow();
}

//多继承
interface Sister extends Father,Mother {
}

//class Son implements Father,Mother //多实现
class Son extends Object implements Father,Mother {
    public void fatherShow() {
        System.out.println("fatherShow");
    }
    
    public void motherShow() {
        System.out.println("motherShow");
    }
}

class InterfaceDemo3 {
    public static void main(String[] args) {
        //创建对象
        //编译看左边
        Father f = new Son();
        f.fatherShow();
        //f.motherShow(); //报错 因为这个是mother的方法
    
        Mother m = new Son();
        //m.fatherShow(); //报错 因为这个是father的方法
        m.motherShow();
    }
}

抽象类和接口的区别

成员变量和成员方法区别

抽象类有变量和常量,有抽象方法和非抽象方法
接口没有变量,只有常量;只有抽象方法

同类型关系之间的区别

类与类 继承,单继承。
类与接口 实现,单实现&多实现。
接口与接口 继承,单继承,多继承

设计理念区别

抽象类被继承,体现的是:is a 的关系,共性功能
接口被实现,体现的是:like a 的关系,扩展功能

★权限修饰符

publicprotected默认private
同类:同一个类中
同包:同一包子类,同一包其它类
子类:同包子类或者不同包子类
其它类:同包其他类或者不同包其它类

所有权限修饰符同类都可以访问
private:同类
default:同包
protected:同包或者子类
public:所有的都可以访问

package A;
/***
 *
 * 在同一类中 可以发现所有的修饰符修饰的变量都可以访问
 * 同时 其他所有的类都可以访问到a
 */
public class A {

    public int a = 0;
    protected int b = 0;
    int c = 0;
    private int d = 0;

    public static void main(String[] args) {
        System.out.println(new A().a);
        System.out.println(new A().b);
        System.out.println(new A().c);
        System.out.println(new A().d);
    }
}
package A;

public class 同一包其他类 {
    public static void main(String[] args) {
        System.out.println(new A().a);
        System.out.println(new A().b);
        System.out.println(new A().c);
         /*
        //不能访问
        System.out.println(new A().d);
        */
    }
}
package A;

public class 同一包子类 extends A {
    public static void main(String[] args) {
        System.out.println(new A().a);
        System.out.println(new A().b);
        System.out.println(new A().c);
         /*
        //不能访问
        System.out.println(new A().d);
        */
    }
}
package B;
import A.A;
public class 不同包其他类 {

    public static void main(String[] args) {
        System.out.println(new A().a);
        /*
        //不能访问
        System.out.println(new A().b);
        System.out.println(new A().c);
        System.out.println(new A().d);
        */
    }
}
package B;
import A.A;

public class 不同包子类 extends A {

    public 不同包子类() {
        System.out.println(new A().a);
        System.out.println(super.b);
         /*
        //不能访问
        System.out.println(new A().c);
        System.out.println(new A().d);
        */
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值