前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【趣学程序】java面向对象(三)

【趣学程序】java面向对象(三)

作者头像
趣学程序-shaofeer
发布2019-07-27 18:27:13
5410
发布2019-07-27 18:27:13
举报
文章被收录于专栏:upuptop的专栏

抽象类

当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的行为方式,那么这些方法都有具体的方法体。但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。

抽象方法的定义:通过 abstract关键字来修饰的类称为抽象类;

代码语言:javascript
复制
abstract class A{}

注意:

  1. 抽象类可以含有普通方法,抽象类可以有零个或者多个抽象方法。抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。
  2. 抽象类不能创建实例对象(不能new)
  3. 需要子类重写所有的抽象方法后才可以创建子类对象,否则子类也必须作为抽象类
代码语言:javascript
复制
abstract class Person{}
class Student extends Person{}
public class Demo2 {    public static void main(String[] args) {        Person p = new Student();//体现的是多态,父类声明实例化子类对象。而不是抽象类实例化    }}

抽象方法

是被 abstract修饰的方法。抽象方法只有返回类型和方法签名,没有方法体。

代码语言:javascript
复制
public abstract void fun1();
[非private访问修饰符]  abstract 返回值类型 方法名称(参数列表);

abstract class Person3{    abstract void show();    abstract void inof();    void turn(){    }}
class NewP extends Person3{    @Override    void show() {    }
    @Override    void inof() {    }    //不覆写的话会报错}
public class Demo15 {    public static void main(String[] args) {        //new Person3();报错!因为抽象类不可以实例化    }}

抽象类的体现-模板设计模式

模板设计模式

抽象类是多个具体子类抽象出来的父类,具有高层次的抽象性;以该抽象类作为子类的模板可以避免子类设计的随意性; 抽象类作为多个子类的通用模板,子类在抽象类的基础上进行拓展,但是子类在总体上大致保留抽象类的行为方式; 编写一个抽象父类,该父类提供了多个子类的通用方法,并把一个或多个抽象方法留给子类去实现,这就是模板设计模式;

模板模式应用的简单规则:

  1. 抽象父类可以只定义需要使用的某些方法,其余留给子类去实现;
  2. 父类提供的方法只是定义了一个通用算法,其实现必须依赖子类的辅助;
代码语言:javascript
复制
//模板模式
//抽象类中包含很多的抽象方法,子类必须去覆写!abstract class Method{    abstract double mul();//返回值类型如果是void的话,下面报错,因为没有返回值,无法引用!    abstract double divid();    void show(){        System.out.println("面积是:"+mul());//周长        System.out.println("面积是:"+divid());//面积    }}
class Square extends Method{    double d;
    public Square(double d) {        super();        this.d = d;    }
    @Override    double mul() {        return d * d;    }
    @Override    double divid() {        return 4 * d;    }}
class Cirle extends Method{    double r;
    public Cirle(double r) {        super();        this.r = r;    }
    @Override    double mul() {        return 2 * 3.14 * r;    }
    @Override    double divid() {        return 3.14 * r * r;    }}
public class Demo16 {    public static void main(String[] args) {        Square s = new Square(5);        s.show();        Cirle c = new Cirle(4);        c.show();    }}

接口(interface)

抽象类是从多个类中抽象出来的模板,若要将这种抽象进行得更彻底,就得用到一种特殊的“抽象类”→ 接口;

例子:生活中听说过的USB接口其实并不是我们所看到的那些插槽,而是那些插槽所遵循的一种规范; 而我们看到的那些插槽是根据USB规范设计出来的实例而已,也就说插槽是USB的实例; 对应不同型号的USB设备而言,他们各自的USB插槽都需要遵循一个规范,遵守这个规范就可以保证插入插槽的设备能与主板正常通信; 对于同一种型号的主板上的多个USB插槽,他们有相同的数据交换方式,相同的实现细节,可认为他们都是同一个类的不同实例

总结:

  1. 接口只定义了类应当遵循的规范,却不关心这些类的内部数据和其方法内的实现细节.
  2. 接口只规定了这些类里必须提供的方法;从而分离了规范和实现.增强了系统的可拓展性和维护性;

好处:

  1. 更好的拓展性
  2. 更好的维护性
  3. 定义一个接口相当于定义了一种标准

interface定义

接口定义一种规范,规定一个类必须做什么,但它不管如何具体去做;

代码语言:javascript
复制
[修饰符] interface 接口名 extends 父接口1,父接口2....
public interface IService {    public abstract void fun1();
}

注意

  1. 接口没有构造方法,不能实例化;
  2. 接口只能继承接口,可以继承多个接口,不能继承类
  3. 接口中没有普通方法,全部都是抽象方法
  4. 接口中的方法默认修饰符都是 publicabstract 可以省略不写
  5. 接口中的成员变量默认修饰符都是 publicstaticfinal 静态常量

接口的使用

格式: publicclassSubImplextendsSuperimplementsIA,IB

代码语言:javascript
复制
让类实现接口,可以实现多个接口,实现的接口必须实现接口中所有的方法。

interface IA {    void a();}
interface IB {    void b();}
class ABImpl implements IA, IB {
    @Override    public void a() {        System.out.println("a");    }
    @Override    public void b() {        System.out.println("b");    }}
public class InterfaceDemo {    public static void main(String[] args) {        //接口不能创建实例,但是可以声明引用类型的变量。        IA ia = new ABImpl();        IB ib = new ABImpl();
        ia.a();        ib.b();    }}

接口和抽象类的比较

相同点:

  1. 都位于继承的顶端,用于被其他实现或继承;
  2. 都不能实例化;
  3. 都包含抽象方法,其子类都必须覆写这些抽象方法;

不同点:

  1. 抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性,可以有普通方法;接口只能包含抽象方法;
  2. 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)

二者的选用:

  1. 优先选用接口,尽量少用抽象类;
  2. 需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;

匿名内部类

  1. 适合只使用一次的类
  2. 不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。
  3. 匿名内部类不能定义构造器,因为匿名内部类没有类名。

格式:

代码语言:javascript
复制
new 父类构造器([实参列表]) 或 接口(){//匿名内部类的类体部分}
例如我们将上面代码中IA,IB两个接口通过匿名内部类的方式来创建其对象:
IA innerIa = new IA() {    @Override    public void a() {        System.out.println("inner a");    }};
IB innerIb = new IB() {    @Override    public void b() {        System.out.println("inner b");    }};
innerIa.a();innerIb.b();

枚举类

特点

  1. 使用enum声明,默认直接继承了java.lang.Enum类,而不是Object类;
  2. 枚举类的对象是固定的,实例个数有限,不可以再new( ),枚举对象后可以跟()。
  3. 枚举元素必须位于枚举类体中的最开始部分,枚举元素后要有分号与其他成员分隔。
  4. 枚举类的构造方法的权限修饰符默认是private;
  5. 一旦枚举对象后面加上{},那么该对象实际是枚举匿名内部类对象;
  6. 所有枚举类都提供一个静态的values()方法(返回该枚举类所有对象组成的数组),便于遍历所有枚举对象;
  7. 所有枚举类都提供一个静态的valueOf(String name)方法, 返回枚举类中对象名等于 name的对象。
代码语言:javascript
复制
//枚举enum Color {    Green, Blue, Yellow;
    @Override    public String toString() {        String ret = super.toString();        switch (this) {            case Green:                ret = "绿色";                break;
            case Blue:                ret = "蓝色";                break;
            case Yellow:                ret = "黄色";                break;
            default:                break;        }
        return ret;    }
}
class Personp {    Color c = Color.Blue;
    void show() {        System.out.println(c);    }}
public class Demo18 {    public static void main(String[] args) {        Color[] color = Color.values();        for (Color c : color) {            System.out.println(c);        }        new Personp().show();    }}输出:绿色蓝色黄色蓝色
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 趣学程序 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 抽象类
  • 抽象方法
  • 抽象类的体现-模板设计模式
    • 模板设计模式
      • 模板模式应用的简单规则:
      • 接口(interface)
        • interface定义
        • 接口的使用
        • 接口和抽象类的比较
        • 匿名内部类
        • 枚举类
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档