目的
学习:
1.抽象类的定义
2.抽象类的规则
3.接口的使用
技术及其使用
一.抽象类
所有的对象都是通过类来描述的,但不是所有类都能描述完全对象,一个不能具体描述出一个对象的类被称为抽象类。
/**
* 抽象类 abstract
* 模板的作用 模具 -> 玩具(颜色不一样 材质不一样)
* 学习路线 ——> C语言 -> java -> 界面 网络 多线程 数据库
*
* */
/**定义一个抽象类 管理学习Android 开发的路线
* 抽象类里面定义使用这个功能就有必要实现的方法或属性
* 抽象类不能实例化 不能创建抽象类的对象
* */
abstract class AndroidStudy{
//定义一个代码块
{
System.out.println("fitness");
}
//定义一个属性 用于保存数据
public String javaBook;
public Dream dream;
//提供一个构造方法
public AndroidStudy(String javaBook,String dream){
this.javaBook = javaBook;
this.dream = new Dream();
this.dream.name = dream;
}
//定义一个静态的常量
public static final String cBook = "C premier";
//定义一个抽象方法 不需要实现 子类来实现
public abstract void studyC();
//定义一个普通方法 已经确定了这个方法的具体实现
public void studyJava(){
System.out.println("参加java培训班");
}
//定义一个内部类 用于管理每个人的理想
class Dream{
public String name;
public void show(){
System.out.println("my dream is : "+name);
}
}
}
如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
声明抽象方法会造成以下两个结果:
1.如果一个类包含抽象方法,那么该类必须是抽象类。
2.任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
3.继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。
总结:
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
二.接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口与类相似点:
1.一个接口可以有多个方法。
2.接口文件保存在 .java 结尾的文件中,文件名使用接口名。
3.接口的字节码文件保存在 .class 结尾的文件中。
4.接口相应的字节码文件必须在与包名称相匹配的目录结构中。
5.接口与类的区别:
6.接口不能用于实例化对象。
7.接口没有构造方法。
8.接口中所有的方法必须是抽象方法。
9.接口不能包含成员变量,除了 static 和 final 变量。
10.接口不是被类继承了,而是要被类实现。
11.接口支持多继承。
接口特性:
1.接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
2.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
抽象类和接口的区别
1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
测试:
/**
* 接口 interface 定义一套方法 用于对象之间的通信
* 接口就是定义一套规则/规范
*
*
* 接口里面默认的变量都是static final 常量
*默认情况下不需要自己写 public static final
* 不能定义变量
*
* 接口里面不能定义代码块
*
* 接口里面不能定义构造方法
*
* 接口里面不能添加普通/对象/实例方法
* 只有抽象方法
* 默认就是 public abstract
*
* 如果需要定义已经有实现的方法
* 使用default
*
* 接口里面可以定义内部类
* 一个类可以实现多个接口
*
* 一个接口可以继承多个接口
* interface testInterface2 extends testInterface
* */
interface testInterface{
public static final int I = 100;
int COUNT =20;
void test();
public void test2();
public abstract void test3();
static class inner{
int name;
public void show(){
System.out.println("woo");
}
}
}
interface testInterface2 extends testInterface{
public static final int I = 100;
int COUNT =20;
void test();
public void test2();
public abstract void test3();
static class inner{
int name;
public void show(){
System.out.println("woo");
}
}
}
class WYClass implements testInterface,testInterface2{
@Override
public void test(){
testInterface2.inner in = new testInterface2.inner();
in.show();
}
@Override
public void test2(){
}
@Override
public void test3(){
}
}
class Te{
public static void main(String[] args){
WYClass go = new WYClass();
testInterface t =new WYClass();
}
}
接口的声明
接口的声明语法格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
实现一个接口的语法,可以使用这个公式:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
实际使用
用接口实现模拟按钮的点击和对代码运行时间的计算
/**
* 管理界面的抽象类 定义了一个界面创建到结束的模板
*
* **/
import java.util.ArrayList;
public class Start {
public static void main(String[] args){
//启动程序 创建界面
MainActivity main = new MainActivity();
//模拟触摸
main.touch();
MyCode code =new MyCode();
code.calculate();
}
}
public abstract class Activity{
//保存这个界面的所有子视图
public ArrayList<View> childs = new ArrayList<>();
//界面创建
public abstract void onCreate();
//界面销毁
public abstract void onDestory();
//将一个子控件添加到主界面上
//接收的时候是用父类去接收子类
//当需要访问子类内容的时候就要降至转化为对应的类
public void addChild(View v){
//保存子类控件
if(v instanceof Button) {
Button btn = (Button)v;
System.out.println(btn.title+"按钮显示到界面上了");
}else {
ImageView img = (ImageView)v;
System.out.println(((ImageView) v).picture+"的图片显示到界面上了");
}
childs.add(v);
}
}
//创建主界面
//管理主界面(程序运行起来的第一个界面)
public class MainActivity extends Activity implements View.onClickListener{
Button btn;
ImageView img;
//构造方法
//当界面被创建 就自动调用oncreate方法
public MainActivity(){
onCreate();
}
@Override
public void onCreate() {
btn = new Button("share","Red");
img = new ImageView("jay zhou");
//将创建的控件添加到当前界面
addChild(btn);
addChild(img);
//如果一个控件需要监听事件 就必须实现监听事件的接口
//告诉按钮是谁在监听这个事件
btn.listener = this;
//2.
//给imageview添加一个事件
img.listener = new View.onClickListener(){
@Override
public void onClick(View v){
System.out.println("图片被点击了");
}
};
}
//模拟触摸屏幕
public void touch(){
//将屏幕触摸的时间传递给按钮
btn.getTouchEvent();
img.getTouchEvent();
}
@Override
public void onDestory() {
}
//当事件触发了 就会来调用这个onClick方法
@Override
public void onClick(View v) {
System.out.println("按钮被点击了");
}
}
public class Button extends View{
String title;
String titleColor;
public Button(String title,String titleColor){
this.title = title;
this.titleColor =titleColor;
}
}
public class ImageView extends View{
String picture;
public ImageView(String picture){
this.picture = picture;
}
}
//管理一个视图显示和事件监听
//什么情况下需要将一个父类做成抽象类(模板)
//1.不能直接创建这个类的对象
//2.这个类里面的某些方法 还不确定如何实现
//
public class View{
//所有视图都共有的属性
String backogoundColor;
String borderColor;
//所有的视图都要监听事件
//定义内部接口 封装
//暂时我不确定是谁要监听 但是要监听事件的人肯定实现了这个接口
onClickListener listener;
public interface onClickListener{
//定义一套方法 约束外部使用这些方法来监听事件
public abstract void onClick(View v);
}
public void getTouchEvent(){
//调用监听者里面的onclick方法
listener.onClick(this);
}
}
public abstract class TimeTemplate {
public abstract void code();
public void calculate(){
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
class MyCode extends TimeTemplate{
@Override
public void code() {
//写自己的测试代码
int[] nico =new int[10000000];
for (int nicos:nico){
System.out.println("1314521"+nicos);
}
}
}
运行结果
result
Be better