Java learning - 2. 接口 & 泛型

目录

抽象

接口(interface)

        定义格式

        接口中的内容

        定义接口例子

        接口具体化        

        使用具体化的接口

泛型

        定义格式

        具体化使用泛型

        泛型接口

        泛型接口与泛型类配合

        泛型方法

        泛型继承


抽象

        在进行接口和泛型的学习前,首先应该知道一个概念叫做抽象

        抽象是不具体定义如何实现,只有一个壳,其内容由用户自己定义的一个概念,比如Arm公司只生产内核的框架,授权给各大厂商,这些厂商在Arm给的框架(技术档案)以及给出的一些功能上,自定义功能,自行组建硬件,这样就实现了抽象

        上一篇文章写到的由属性和方法组成,其中属性是抽象的,其具体内容要实例化后才能完成具象,但是方法是具体的,在类的定义中就给出了具体方法的实现

        这里就会遇到一种情况,这里我以KFC百事可乐的制造方法为例,有一个KFC类,其中有制造可乐的方法,但是如果有一天一家思路新奇的KFC打算进行改革,想要将可口可乐作为制造品,该怎么办呢,由于KFC类早已封装完成,不能对KFC类中的制造方法进行修改,此时可能想到的方法是新定义一个类继承KFC类,在这个子类中对制造方法进行重写,如下

public class KFC {
    public void make_coke(){
        System.out.println("pepsi");
    }
}

public class KFC_new extends KFC {
    public void make_coke(){
        System.out.println("coke cola");
    }
}

        这样子每次有人想创新就得新定义一个子类,有没有一种办法能够不用定义一个新的子类,但是能够用自己的方式来写方法呢?接口(interface)应运而生!接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力

接口(interface)

        定义格式

        interface <interface_name>{...},如下定义一个接口Make_Coke

interface Make_Coke{ }

        接口中的内容

        1. 接口中可以定义抽象方法,也就是没有方法体的方法,默认为public static abstract

        2. 接口中可以定义属性,但是是常量,必须赋值,默认为public static final

        3. 接口中也可以定义非抽象方法,但是必须用default修饰

        定义接口例子

interface Make_Coke{
    //抽象方法
    void make_coke();
    //非抽象方法
    default void mydefault(){
        System.out.println("default");
    }
}

        接口具体化        

        一个接口可以被一个类实现,或者说具体化,但是这个类必须实现这个接口中的所有抽象方法,也可以重写其非抽象(default)方法,要实现这个接口,使用implements关键字

        格式为:class <class_name> implements <interface_name>,在上例中可以具体化一个百事可乐类,一个可口可乐类,其中分别实现了不同的方法,一个制造百事可乐,一个制造可口可乐

class Make_Pepsi implements Make_Coke{
    public void make_coke() {
        System.out.println("make pepsi");
    }
}

class Make_Cokecola implements Make_Coke{
    public void make_coke() {
        System.out.println("make cokecola");
    }
}

        这也是接口存在的意义,能够调用相同的上层方法,但是底层实现却不同,有利于封装

        接口还有一个重要的地方,接口可以实现多继承,而类只能单继承,比如我又有一个制造果汁的类Make_Juice,可以用一个类来继承制造果汁的同时继承制造可乐,并在具体实现方面个性化地制造百事可乐和制造橙汁,多继承提供了只需要一个类就能实现多个接口的便利

interface Make_Coke{
    void make_coke();
}

interface Make_Juice{
    void make_juice();
}

class Make_Drink implements Make_Coke,Make_Juice{
    public void make_coke() {
        System.out.println("make pepsi");
    }
    public void make_juice() {
        System.out.println("make orange juice");
    }
}

        使用具体化的接口

        这里有一种简单的使用方法,直接声明Make_Cokecola类mcc,然后使用其中的方法

class test1{
    public static void main(String[] args) {
        Make_Cokecola mcc = new Make_Cokecola();
        mcc.make_coke();
    }
}

        还可以联想并利用上一篇中向上转型的原理,声明一个Make_Coke类mc,但是创建的是继承了它的Make_Cokecola类,这里也体现了Java的多态特性!

class test1{
    public static void main(String[] args) {
        Make_Coke mc = new Make_Cokecola();
        mc.make_coke();
    }
}

        如果想在KFC类中实现的话,只需要在KFC类中定义一个Make_Coke类KFC_mc,并封装一下make_coke函数,随后在实例中调用即可!

public class KFC {
    Make_Coke KFC_mc;
    public void make_coke(){
        KFC_mc.make_coke();
    }
}

class test1{
    public static void main(String[] args) {
        KFC kfc = new KFC();
        kfc.KFC_mc = new Make_Cokecola();
        kfc.make_coke();
    }
}

        如果KFC将其类写成这种形式,就给了连锁商家一些能够DIY彰显个性的东西!联想到生活中的例子USB,一台电脑有一个USB接口,可以连接许多设备,这些设备类型不同,比如手机、MP3、键盘等,这些都可以implements USB接口,然后在电脑上使用,但是各自的驱动文件会在各自对应的抽象方法实现中体现,这样就实现了USB接口的复用,这其实在生活中就是一个“标准”,而在Java中这个“标准”就是接口定义的!

泛型

        在学习泛型前就有意无意间知道泛型在Java中的重要地位,Java中的泛型与C++中的模板其实有相通之处,都是为了实现通用设计

        泛型的本质是参数化类型,即给类型指定一个参数,然后在编写代码时都是用这个参数,然后在具体使用时再具体此参数,那样这个类型就可以在使用时决定了,而非在编写代码时就定死,这样也就实现了设计的通用化

        想象一个容器V,在设计时如果规定其可以容纳的内容类型是String,则在后续使用中就只能在其中放String,如果我用泛型的概念,在设计它时不规定它的内容类型,而是用泛型来规定,在后续使用时由用户来确定这个泛型到底是什么类型,是不是就实现了通用化?

        定义格式

        泛型可以用在类、接口和方法中,在一个目标后面加上<>,尖括号中用一个符号表示该泛型,可以自定义,这样就可以了,下面给了定义例子

public class myVector<T>{
    private T v;
    myVector(T value){
        this.v = value;
    }
    public T get_v(){
        return v;
    }
};

        具体化使用泛型

        上面定义了一个带有泛型的myVector类,在使用时,只需要在创建一个myVector类时在泛型处加上用户所需要的类型即可

class test2{
    public static void main(String[] args) {
        myVector<Integer> v_int = new myVector<>(1);
        myVector<String> v_string = new myVector<>("v_string");
        System.out.println(v_int.get_v());
        System.out.println(v_string.get_v());
    }
};

        这里需要注意以下几点:

        1. 在具体化泛型时,在<>中的类型需要写全拼,并且第一个字母大写,比如int要写成Integer,char要写成Character,double要写成Double

        2. new时<>中不带任何参数,空着就行

        3. 使用泛型时,每处泛型都必须相同,否则编译错误!

        上面提到的是泛型类,下面看看泛型接口和泛型方法

        泛型接口

        与泛型类一样,泛型也可以应用于接口,原理相同,这里直接给一个例子

interface Get<T>{
    T get(T[] a,int i);
};

        同样的,可以具体化这个接口

class Get_String implements Get<String>{
    public String get(String[] s,int i){
        System.out.println(s[i]);
        return s[i];
    }
};

class Get_Int implements Get<Integer>{
    public Integer get(Integer[] a,int i){
        return a[i];
    }
};

        根据自己的需求,可以实例化不同的Get子类

        泛型接口与泛型类配合

        泛型接口可以跟泛型类配合,实现更加强大的通用化,这里也直接给出上面例子的拓展

public class myVector<T>{
    private T[] values;
    Get<T> myvector_get;
    myVector(T[] value){
        this.values = value;
    }
    public T get(int i){
        return myvector_get.get(values,i);
    }
};

        下面给出测试代码,可以正确get到第2个元素3

class test2{
    public static void main(String[] args) {
        Integer[] a = {1,2,3,4,5};
        myVector<Integer> myV_int = new myVector<>(a);
        myV_int.myvector_get = new Get_Int();
        System.out.println(myV_int.get(2));
    }
};

        或者也可以不指定myV_int的泛型类型,直接空着,也能自动识别

myVector myV_int = new myVector<>(a);

        泛型方法

        泛型可以用于方法,实际上在上面两个例子中已经用到了,这里不做赘述,直接上例子

class test{
    public <T> T generea(T t){
        return t;
    }
}

        测试如下

class test2{
    public static void main(String[] args) {
        test tt = new test();
        System.out.println(tt.generea("hello"));
    }
};

        泛型继承

public class Caculate<T extends String> {
    private T num;
}

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值