Java自学之抽象类与接口

面向对象程序设计中,类继承的主要作用的扩充已有类的功能。子类可以根据自己的需要选择是否要覆写父类中的方法,所以一个设计完善的父类是无法对子类做出任何强制性的覆写约定。为了解决这样的设计问题,提出抽象类的概念,抽象类与普通类相比唯一增加的就是抽象方法的定义,同时抽象类在使用时要求必须被子类所继承,并且子类必须覆写全部抽象方法

抽象类基本定义

抽象类需要使用abstract class进行定义,并且在一个抽象类中也可以使用abstract关键字定义若干个抽象方法,这样抽象类的子类就必须在继承抽象类时强制覆写全部抽象方法。

abstract class Message {
	private String type;
	// 定义抽象方法,抽象方法只定义方法名,没有方法体
	public abstract String getConnectInfo();
    // 普通方法
    public void setType(String type) {
        this.type = type;
    }
    public String getType() {
        return this.type;
    }
}

使用抽象类

class NetMessage extends Message {
	@Override
	public String getConnectInfo() {
		return '获取【' + super.getType() + '】消息连接……'
	}
}
class JavaDemo {
	public static void main(String[] args) {
		Message msg = new NetMessage();
		msg.setType('UITHML');
		System.out.println(msg.getConnectInfo());
	}
}

抽象类最大的特点就是无法自己直接进行对象实例化操作,所以在实际项目开发中,抽象类的主要目的是进行过度操作。当你要使用抽象类进行实际开发的时候,往往都是在你设计中选哟解决类继承问题时所带来的代码重复问题。

抽象类相关说明

  • 抽象类必须由子类继承,所以在定义时不允许使用final关键字定义抽象类或抽象方法。
  • 抽象类中可以可以定义成员属性和普通方法,为了可以为抽象类中的成员属性初始化,可以在抽象类提供构造方法。子类在继承抽象类时会默认调用父类的无参构造,如果抽象类没有提供无参构造方法,则子类必须通过super()的形式调用指定参数的构造方法。
  • 抽象类中允许没有抽象方法。
  • 抽象类中可以提供static方法,并且该类方法不受到抽象类实例化对象的限制。
  • 抽象类只能被继承,不能使用new关键字实例化。

包装类

Java是一门面向对象的编程语言,所有的设计都是围绕着对象这一核心概念展开,但与这一设计有所违背的就是基本数据类型(byte、short、int、long、float、double、char、boolean),所以为了符合这一特点可以利用类的结构对基本数据类型进行包装。

class Int {
	private int data;
	public Int(int data) {
	  this.data = data;
	}
	public int intValue() {
	  return this.data;
	}
}
class JavaDemo {
	public static void main(String[] args) {
		Object obj = new Int(10); // 【装箱操作】将基本数据类型保存在包装类中
		int x = ((Int) obj).intValue();  // 【拆箱操作】从包装类对象中获取基本数据类型
	}
}

本程序定义了一个int包装类,并且在类中存储有int数据信息,利用这样的包装处理就可以使用Object类来进行基本数据类型的接受,从而实现参数的完全统一处理。

Java中包装类可以分为两种类型。

  • 对象型包装类(Object直接子类):Boolean、Character。
  • 数值型包装类(Number直接子类):Byte、Short、Integer、Long、Float、Double。

装箱与拆箱

基本数据类型的包装类都是为了基本数据类型转换为对象引用而提供的,这样对于基本数据类型与包装类之间就有了以下的转换操作关系。

数据装箱:将基本数据类型保存到包装类中,一般可以利用包装类的构造方法完成。

数据拆箱:从包装类中获取基本数据类型。

数据类型转换

在项目编写中往往需要提供有交互式的运行环境,即需要根据用户输入内容的不同来进行不同的处理,但是在Java程序中所有输入的内容都会利用String类型来描述,所以就需要通过包装类来实现各自不同数据类型的转换。

class JavaDemo {
	public static void main(String[] args) {
		String str = '123'; //  声明字符串数值
        String str1 = 'true'; // 声明字符串true
		int num = Integer.parseInt(str);  //  字符串转换成int
        boolean flag = Boolean.parseBoolean(str); // 字符串转换成Boolean,结果为false
        boolean flag1 = Boolean.parseBoolean(str1); // true
	}
}

字符串转换成boolean型数据时,如果字符串的组成时true或false则可以按照要求进行转换,如果不是,则为了避免程序出错,会统一转换为false。

接口

接口在实际开发中是由一种比抽象类更为重要的结构组成,接口的主要特点在于其用于定义开发标准。

在Java中接口属于一种特殊的类,需要通过interface关键字进行定义,在接口中可以定义全局变量、抽象方法(必须是public访问权限)、default方法和static方法。

定义标准接口

interface IMessage {
	public static final String INFO = 'www.uihtml.cn'; // public static final可省略
	public abstract String getInfo(); // abstract可省略
}

本程序定义了一个IMessage接口,由于接口中存在有抽象方法,所以无法被直接实例化,其实用原则如下:

  • 接口需要被子类实现,子类利用implements关键字可以实现多个父接口。
  • 子类如果不是抽象类,那么一定呀覆写接口中的全部抽象方法。
  • 接口对象可以利用子类对象的向上转型进行实例化。
class MessageImpl implements IMessage {
	@Override
	public String getInfo() {
	  return 'www.uihtml.cn'
	}
}
class JavaDemo {
	public static void main(String[] args){
		IMessage msg = new MessageImpl(); // 向上转型,子类实例化父接口
        System.out.println(msg.getInfo());
	}
}

子类可以继承父类也可以实现父接口

class 子类 [extends 父类] [implements 接口1,接口2,...] {}

如果出现混合应用,则要采用先继承(extends)再实现(implements)的顺序完成,同时一定要注意,子类接口的最大特点在于可以同时实现多个父接口,而每一个子类只能通过extends继承一个父类

interface IMessage {
	public static final String INFO = 'www.uihtml.cn';
	public abstract String getInfo();
}
interface IChannel {
	public abstract boolean connect();
}
abstract class NetMessage {
	public abstract boolean getNetConnect();
}
class MessageImpl extends NetMessage implements IMessage,Ichannel {
    @Override
    public boolean connect() {
        return true;
    }
    @Override
    public boolean getNetConnect() {
        return true;
    }
    @Override
	public String getInfo() {
	  if (this.connect()) {
	  	if(this.getNetConnect()) {
	  		return '【网络正常,链接到uihtml.cn】';
	  	} else {
	  		return '【网络异常,无法链接到uihtml.cn】';
	  	}
	  }
	  return '【默认消息】' + IMessage.INFO;
	}
}
class JavaDemo {
	public static void main(String[] args) {
		IMessage msg = new MessageImpl();
		System.out.prinltn(msg.getInfo());
	}
}

Java中的extends关键字除了具有类继承的作用外,也可以在接口上使用,以实现接口的继承关系,并且可以同时实现多个父接口。

interface IMessage {
	public static final String INFO = 'www.uihtml.cn';
	public abstract String getInfo();
}
interface IChannel {
	public boolean connect();
}
interface IService extends IMessage,IChannel {
	public String service();
}
class MessageService implements IService {
	@Override
	public boolean connect() {
		return true;
	}
	@Override
	public String getInfo() {
		return IMessage.INFO;
	}
    @Override
    public String service() {
        return '服务消息:www.uihtml.cn';
    }
}

本程序在定义IService接口时,让其继承了IMessage、IChannel两个父接口,这样IService接口就有了两个父接口定义的所有抽象方法。

接口时面向对象程序设计中最为重要的话题,在实际项目中的核心用处是实现方法名称的暴露与子类的隐藏

接口定义加强

在接口中使用default定义普通方法

interface IMessage {
	public String message();
	// 定义普通方法,该方法可以被子类继承或覆写
	public default boolean connect() {
		System.out.println('建立默认订阅消息通道连接');
        return true;
	}
}
class MessageImpl implements IMessage {
	@Override
	public String message() {
		return 'www.uihtml.cn';
	}
}
class JavaDemo {
	public static void main(String[] args) {
		IMessage msg = new MessageImpl();
		if (msg.connect()) {
			System.out.println(msg.message());
		}
	}
}

本程序在IMessage接口中利用default定义了普通方法,这样接口中的组成就不再只有抽象方法,同时这些default定义的普通方法也可以直接被子类继承。

接口中定义普通方法的意义在于:便于扩充接口功能,同时简化设计结构。

在接口中定义static方法

使用default定义的普通方法需要通过接口实例化对象才可以调用,而为了避免实例化对对象的依赖,在接口中也可以使用static定义方法,此方法可以直接利用接口名称调用

interface IMessage {
	// 定义抽象方法
	public String message();
    // 定义普通方法
    public default boolean connect() {
        System.out.println('建立默认消息订阅连接通道');
        return true;
    }
    // 定义static方法,可以通过接口名称直接调用
    public static IMessage getInstance() {
        return new MessageImpl();
    }
}
class MessageImpl implements IMessage{
	@Override
	public String message() {
		if(this.connect()) {
			return 'www.uihtml.cn'
		}
		return '没有消息需要发送'
	}
}
class JavaDemo {
	public static void main(String[] args) {
		IMessage msg = IMessage.getInstance();
		System.out.println(msg.message());
	}
}

定义接口标准

interface IUSB {
	public boolean check();
	public void work();
}
class Computer {
	public void plugin(IUSB usb) {
		if (usb.check()) {
			usb.work();
		} else {
			System.out.println('硬件出现问题,无法工作……');
		}
	}
}
class Keyboard implements IUSB {
	@Override
	public boolean check() {
		return true;
	}
    @Override
    public void work() {
        System.out.println('通过键盘,键入网址:www.uihtml.cn');
    }
}
class JavaDemo {
	public static void main(String[] args) {
		Computer computer = new Computer();
		computer.plugin(new Keyboard());
	}
}

抽象类与接口的区别

区别抽象类接口
关键字abstract classinterface
组成常量、变量、抽象方法、普通方法、构造方法全局常量、抽象方法、普通方法、静态方法
权限可以使用各种权限只能是public
关系一个抽象类可以实现多个接口接口不能继承抽象类,却可以继承多接口
使用子类使用extends继承抽象类子类使用implements实现接口
设计模式模板设计模式工厂设计模式、代理设计模式
局限一个子类只能够继承一个抽象类一个子类可以实现多个接口

原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/java/java-abstract-class-interface.html

Like (0)
Donate 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
Previous 2020年12月3日
Next 2020年12月8日

相关推荐

  • STS插件mybatis-generator安装及使用

    断断续续学习Java也有好长时间了,没有师傅带,没有项目练手,学习超级慢,也很烦。视频、书籍翻看了一大推,还是没有目标。 相信滴水成海,外加条条大路通罗马,只要坚持,自己终能达成目…

    2019年12月27日
    2.1K
  • spring boot练习篇之用户登录系统【接口篇】

    写在前面 抛弃JSP,只做纯粹的前后端分离项目。 作为一个资深前端工作者,想要转JavaWeb开发,无论是书籍,还是网上视频、资料,竟然没有一篇能清楚明白地讲解怎样搭建一个前后端分…

    2021年5月25日
    1.5K
  • spring4.x学习之创建工程

    断断续续学习Java有两三个月了,目前还是处于入门阶段。关于java及spring那些的设计理念方面的理论知识,不花费大量精力及时间是看不懂的(至少对于我这么一个前端转后端的初学者…

    2019年3月19日
    1.7K
  • spring boot练习篇之用户登录系统【接入数据库】

    抛弃JSP,只做纯粹的前后端分离项目。 写在前面 学习基础知识是枯燥无味的,之所以会这样,多数是因为心不静,对于如何运用它,感到茫然。所以建议大家在学习Java基础知识的时候,一定…

    2021年5月28日
    1.1K
  • Java自学之多线程编程

    多线程编程是Java语言最为重要的特性之一。利用多线程技术可以提升单位时间内的程序处理性能,也是现代程序开发中高并发的主要设计模式。 进程与线程 进程是一个应用程序。线程是一个进程…

    2020年12月16日
    1.4K
  • JAVA学习路线之夯实基础

    第一章 开发环境 JDK(Java SE Development Kit),Java标准版开发包,提供编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行环…

    2020年1月14日
    1.5K
  • Spring Tools学习之JAVA开发环境搭建【windows 10】

    一直以来都想学习JAVA,但是苦于找不到门路,网上学习资料要不看不懂,要不需要金钱。 终于,迫于生活与年龄的压力,下定决心,学习JAVA。 写下此文档,记录一下自己学习JAVA之路…

    2018年12月6日
    2.7K
  • MyBatis之MyBatis-Generator标签配置及意义

    DTD 标签 <generatorConfiguration/>: 根标签,所有的配置都必须在该标签内配置;没有属性 <properties/>: 主要引用外部的pro…

    2019年12月27日
    1.7K
  • Java自学之反射机制

    重用性是面向对象设计的核心原则。为了进一步提升代码的重用性,Java提供了反射机制。反射技术首先考虑的是“反”与“正”的操作,所谓的“正”操作,是指当开发者使用一个类的时候,一定要…

    2020年12月24日
    1.1K
  • Java自学之内部类

    内部类是一种常见的嵌套结构,利用这样的结构使得内部类可以与外部类共存,并且方便地进行私有操作的访问。 内部类基本概念 内部类(内部定义普通类、抽象类、接口的统称)是指一种嵌套的结构…

    2020年12月14日
    1.3K

发表回复

Please Login to Comment