[Java]开发安卓,你得掌握的Java知识7——抽象类与接口

0.前言

  • 上一篇文章(Java知识6)我们讲解了继承、多态等知识点
    今天我们讲两个重点:抽象类和接口

  • 若想要了解“类”的主要知识,可以去看前面的文章
    《[Java]开发安卓,你得掌握的Java知识5》
    《[Java]开发安卓,你得掌握的Java知识4》
    《[Java]开发安卓,你得掌握的Java知识3》

  • 由于最终目的是要开发安卓app,
    因此这里使用的IDE是AS(Android Studio)
    (不会使用的可以参考下面这篇文章中的例子)
    《[Java]开发安卓,你得掌握的Java知识2》

1.本文主要内容简介

  • 抽象类

  • 接口的概念、用法、思路

  • 一个实际的例子(思路、代码)

2.基础知识讲解

2.1什么是抽象类

  • 抽象类就是一个模板

  • 抽象类有两种理解方式(算是两种用法):
    (1)某种类需要规定出一些规则,规定出子类要去实现什么属性、方法,发挥一种统筹的作用

    (2)继承这模板,可以理解为能获得额外的能力(属性、方法)
    让继承该模板(抽象类)的类获得某些额外的属性、方法
    (比如人高空坠落会直接摔死,要是带了降落伞就能够缓慢降落)

  • 使用方法:首先定义一个抽象类,然后用其他类去继承它,以获得它的一些属性、方法

  • 定义方法:abstract public 类名

public abstract class Activity {

}

要点:

  • 抽象类里面也会分抽象方法,和方法,方法也用abstract修饰

  • 抽象方法不能实现,只能声明,如:
    public abstract void onCreate();

  • 抽象类的普通方法要实现

  • 继承抽象类的子类,必须实现抽象方法,但可以不管普通方法

public abstract class Activity {
    //抽象方法
    public abstract void onCreate();
    
    //普通方法
    public void addChilds(View v){
        this.viewList.add(v);
    }

}
public class MainActivity extends Activity{
      @Override
      public void onCreate(){
            System.out.println("hello");
      }
}

2.2什么是接口

  • 从概念上来讲,
    接口就是一种,需要使用者必须遵守的规则

  • 从程序员编写代码角度来讲
    接口就是让两种类能联系起来的工具

  • 为什么要用接口?
    ①有时候需要遵守上层指定的规则
    ②需要联系两种类

基本定义方法:

public interface OnClickListener{
        //定义一个内部接口,只有一个onClick方法
        void onClick("有参数,但暂时别管");
}
public class Test implements OnClickListener{

        @Override
        public void onClick("有参数,但暂时别管") {
             //具体实现
       }
}

这样Test类就会实现这个接口了,但是只知道这些还远远不够

  • 接口为什么可以联系两种类?
    我的见解是:
    因为其中一个类实现了接口,第二个类看到了就会去调用
    因此两个类实现了联系

  • 简单一些来讲,定义了一个接口后,之后会出现:
    ①类A:实现接口的
    ②类B:调用类A中已经实现好的接口的方法(其实就是接口回调)
    一个实现,一个调用,然后两个类就会有所联系

  • 接口在哪个类里面实现呢?
    “知道这个接口该如何实现的类”里面
    "知道到底会发生什么的那个类"里面实现

  • 如果还对接口的概念很模糊,我们不妨想象一下场景:
    A住在一间没有窗户、门,只有墙的房子里,然后他在墙上凿了一个洞,B每天都将指定大小的食物通过这个洞来给他送食物

在这里,A就是实现接口的类,B就是负责回调的类,指定大小就是规则,而那个洞,就是接口

public class View {
    OnClickListener listener ;

    public void getTouchEvent(){
        //接口回调
        listener.onClick(this);
    }
}
interface OnClickListener{
        //定义一个内部接口,只有一个onClick方法
        void onClick(View v);
}

public class MainActivity implements OnClickListener{
    View v = new View();
    public MainActivity() {
          v.listener = this;
    }

    public void touch(){
        //发消息说我做好了
        v.getTouchEvent();
    }
    @Override
    public void onClick(View v) {
        System.out.println("hello");
        }
    }
}
  • 分析一下:

(1)View类中定义了一个接口变量listener,
一个方法用于调用接口的方法(从MainActivity的touch函数找到了View类中的方法,该方法又跑回去调用接口,即接口回调)

(2)接口中只定义了一个未实现的方法onClick

(3)MainActivity中,将自身的引用付给了View类中那个接口变量,并且在类的最后定义了onClick具体怎么做(接口的实现)

(4)View类中的接口变量listener只要将它用实现接口的类(MainActivity)的对象的引用赋值(这里体现为this),就可以通过listener调用在MainActivity中实现的接口的方法onClick

==================================分割线==================================

2.3接口的编写思路

  • 先考虑你的接口需要联系哪两个类

  • 这两个类一个负责实现(类A),一个负责调用(类B)

  • "知道到底会发生什么的那个类"里面实现接口

  • 在负责调用的类中声明一个接口变量

  • 然后将这个实现接口的类的对象的引用赋值给接口变量

  • 在负责调用的类(B)中,
    通过接口变量调用负责实现的类(A)已经实现好的接口的方法

3.知识实际运用

  • 我们模拟Android中,主界面里添加按钮以及按钮的点击事件


  • 其中接口变量要用MainActivity的对象的引用赋值这一点没有表现出来,但是这一点反而是极其重要的

==================================分割线==================================
  • 首先我们定义一个抽象类Activity
public abstract class Activity {
    //用来存放所有控件
    public List viewList = new ArrayList<>();

    public abstract void onCreate();
    public abstract void onDestory();

    public void addChilds(View v){
        this.viewList.add(v);
    }
}

其中List用来存放所有的View变量(即存放所有的控件)
抽象方法onCreate与onDestory需要继承类来具体实现

==================================分割线==================================
  • 接下来我们看View类,View类有两个属性:边框颜色与背景颜色
    public String backgroundColor;
    public String boderColor;
    由于我们要使用的接口与View有关,因此可以考虑直接定义为内部接口(当然定义为外部的其实也行)
    public interface OnClickListener

  • getTouchEvent方法是用来接收消息用的。
    因为我们只是模拟点击事件,所以通过MainActivity的Touch方法调用View类里面的getTouchEvent方法,可以模拟点击

public class View {
    public String backgroundColor;
    public String boderColor;

    OnClickListener listener ;

    //B请求完成的任务
    public interface OnClickListener{
        //定义一个内部接口,只有一个onClick方法
        void onClick(View v);
    }

    //接受A发送过来的消息并且拆开
    public void getTouchEvent(){
        //接口回调
        listener.onClick(this);
    }

  • Button类继承自View类,复杂的内容都在View中实现了,因此Button内容比较简单(属性+构造函数):

public class Button extends View {
    public String title;
    public String titleColor;

    public Button(String title, String titleColor) {
        this.title = title;
        this.titleColor = titleColor;
    }
}
==================================分割线==================================
  • 最后我们来看MainActivity类,它继承与Activity这个抽象类,还要实现接口,因此标题就比较长:
public class MainActivity extends Activity implements View.OnClickListener
  • 继承抽象类的继承类必须实现抽象方法:`
  Button btn = new Button("开始","Black");
  @Override
   public void onCreate() {
        System.out.println("界面被加载了");
        btn.listener = this;
        imageView.listener = this;
        addChilds(btn);
        addChilds(imageView);
    }

    @Override
    public void onDestory() {
        System.out.println("界面被销毁了");
    }
  • 这里的btn.listener = this;是十分重要的,就是在网上随便都能搜到的接口回调的概念中所写的:
    把实现接口的对象的引用(MainActivity里的this)赋值给接口变量(listener),就能通过这个接口变量调用已经实现的接口的方法:
@Override
    public void onClick(View v) {
            System.out.println("按钮被点击了");
    }
  • 在View中进行回调(调用这个实现好的方法):
 public void getTouchEvent(){
        //接口回调
        listener.onClick(this);
    }
  • 在MainActivity里模拟点击:(即调用View中的getTouchEvent)
 public void touch(){
        //发消息说我做好了
        btn.getTouchEvent();
        imageView.getTouchEvent();

    }
==================================分割线==================================
  • 最终,MainActivity代码如下:
public class MainActivity extends Activity implements View.OnClickListener{
    Button btn = new Button("开始","Black");
    public MainActivity() {
        onCreate();
    }

    //用来模拟点击事件(A发送消息给B)
    public void touch(){
        //发消息说我做好了
        btn.getTouchEvent();
        imageView.getTouchEvent();

    }

    @Override
    public void onCreate() {
        System.out.println("界面被加载了");
        btn.listener = this;
        addChilds(btn);
    }

    @Override
    public void onDestory() {

    }

    //发送给B的消息,告诉B是如何完成的
    @Override
    public void onClick(View v) {
            System.out.println("按钮被点击了");
    }
}

4.总结

(1)本文讲述了Java语言中十分重要的两个知识点:抽象类、接口
这两个知识点都是概念简单,但实际运用却十分有难度,尤其是接口,容易将人们绕晕。不过反复观看上文中的诸多例子,应该能对理解有所帮助。
(2)鉴于这两个知识点不容易理解透彻,建议大家要多一些去实践练习,从实践中寻找规律、方法,通过自己、别人的程序来总结出自己的一套理解体系,这样才能达到更好的效果

你可能感兴趣的:([Java]开发安卓,你得掌握的Java知识7——抽象类与接口)