抽象
还记得在校期间上《大学物理》课的时候,老师在讲物质之间的万有引力定律,其实我内心不是很理解,就感觉有点点抽象,在生活中没有实际应用。
换句话说,我们看不见,摸不着,但不能否认他的存在。
又比如说,水果就是一个抽象概念。
“吃水果”,代表吃苹果香蕉梨等具体的水果,而不是“水果”这个物质。
在Java面向对象编程中,也有“抽象”这一个概念,Java提供了abstract关键字。
abstract
abstract是Java语言中一个重要的关键字,是表示抽象的修饰符,可以修饰类和方法,被修饰的类和方法分别被称为抽象类和抽象方法。
比如水果类就是一个抽象类,具体到某种水果的实现时,总是归类于某类水果种类。
所以说,在需要某个抽象类的具体实例化时,只能用具体类的实例来代替。
而且,抽象类不能实例化,不能new一个新对象。
抽象类
在Java中,抽象类可以理解为一个半成品,需要子类继承该抽象类,并且覆盖抽象方法,这样子类才有new对象的能力。
但如果子类还是没能实现父类的抽象方法,那么子类也是抽象类,可以无限循环下去。
抽象类一般位于抽象层,表示该类的设计还没完善,还没得到具体解释,必须在子类进一步完善之后,才可以实例化对象。
创建一个抽象类:User
package cn.zwz; public interface User { void say(); }
创建User类的实例化:Student
package cn.zwz; public class Student implements User{ @Override public void say() { System.out.println("我是学生"); } }
Student类实现了抽象类User的say方法,才能实例化对象进行调用方法:
package cn.zwz; public class Main { public static void main(String[] args) { Student student = new Student(); student.say(); } }
Java的abstract有一定的约束条件,比如:
1.抽象类可以没有抽象方法,如:
public abstract class User { }
2.在一个类中存在抽象方法时,该类会变成抽象类
public abstract class User { abstract void say(); }
3.类的构造方法不能抽象化
public abstract class User { private String name; private int age; // 错误 abstract public User(String name, int age) { this.name = name; this.age = age; } }
4.类的静态方法不能抽象化
public abstract class User { /** * 错误 */ public abstract static int add(int a,int b) { return a + b; } }
5.抽象类抽象方法不能被final修饰
public abstract class User { private String name; private final int age; // 错误 }
6.抽象方法不能和public等权限关键字连用。
public abstract class User { private String name; private abstract int age; // 错误 }
接口
在Java程序设计中,不支持多继承,但支持实现多个接口。
Java提供了interface关键字来定义接口,可以理解为是一种规范或者一种标准。
Java采用单一继承机制,多继承的使用场景则用接口来弥补。
比如有一名工人张三,在人类生物学角度看,只有一位生物学意义上的父亲。但对张三来说,在不同场景下有不同的身份,在学校是一个学生,在公司是一名软件工程师,在超市是一名消费者…根据传统的面向对象概念,张三必须要有学生父亲,才能成为学生;必须要有一名消费者父亲,才能成为消费者…这显然是不成立的。
Java如何实现?就是用了接口的概念,张三接了学生的口,那么他就是学生,接了消费者的口,那么他就是消费者。
又比如说生活中各式各样的标准件,比如A4纸,无需提供纸张的长宽度,即可完成打印;比如电器的220V电压,无需提供电阻和电流值;又比如说软考,我们通过学习成长,拿到了软考证书,就可以去当软件工程师。
接口就是规范、标准,在日常生活中有着各式各样广泛的应用。在Java开发中也是这样,开发者在设计接口时,可以不关注细节,只关心接口的功能和数据格式要求。
比如下面的一个User接口
public interface User { /** * 要实现说话功能 */ public void say(); /** * 要实现加法计算功能 * @param x * @param y * @return */ public int add(int x,int y); }
在Java程序设计中,接口的出现让面向对象程序设计理念前进了一大步,使得代码能够更好的模拟现有世界。
接口的具体实现
在Java中,一个类可以通过关键字 implements 申明自己实现的接口。
如果需要实现多个接口,用逗号隔开即可。
如下Student学生类实现了User接口。
public class Student implements User{ @Override public void say() { System.out.println("我是一名学生!"); } @Override public int add(int x, int y) { return x + y; } }
Student类实现了User接口,和继承机制一样,继承了接口中定义的常量和抽象方法。
常量可以直接使用,但抽象方法需要在类中提供具体实现;也可以不实现且继续成为抽象类,不能实例化对象。
接口和抽象类的关系
接口是抽象类的子集,是抽象类的一种特殊实现。
接口中所有方法都必须是抽象的,但抽象类中可以有不抽象的方法。
接口中方法默认为public、abstract,抽象类中默认为public、static、final,两者存在明显差异。
接口不能存在构造方法,而抽象类可以。
接口没有普通成员变量,但抽象类可以。
接口不能存在静态方法,但抽象类可以。
Java类可以实现多个接口,但只能继承一个抽象类。
接口的作用
从以上抽象类和接口的对比中可以发现,接口是在系统架构设计方面发挥更多的作用,主要用于定义模块之间的关联信息。而抽象类在实际编程中提供更好的作用,可以实现代码的复用,降低代码的耦合性。
多态机制
多态是面向对象程序设计的一大特性,也是一个基本的设计原则。
对于同样一个触发条件,不同对象的响应事件是不一样的,也就是多态。
在生物学的多样性,也就是Java的多态机制。
Java可以通过方法重载、方法覆盖来实现多态机制,在不同的应用场景有着丰富的应用场景。