抽象类:包含一个抽象方法的类称为抽象类。抽象方法是只声明而未实现的方法;
所有的抽象方法必须使用abstract关键字声明,所有的抽象类也必须使用abstract关键字声明
例如:
abstract class A1{
public abstract void fun();
}
1、不能直接进行实例化的操作,但是可以声明,如果想使用抽象类则必须依靠子类。
2、抽象类必须被子类继承,并且被继承的的子类需要实现抽象类中的全部抽象方法。
3、不能使用final声明
4、抽象类中允许有构造方法,但是此构造方法是不能直接被调用的,是交给子类去调用的,子类对象实例化过程,永远是先调用父类中的构造方法。
5、抽象类中的属性如果想要初始化,则肯定还是依赖构造方法
public class AbstractDemo {
public static void main(String args[]) {
B1 b1 = new B1();
b1.fun();
}
}
abstract class A1 {
public abstract void fun();
}
class B1 extends A1 {
@Override
public void fun() {
// TODO Auto-generated method stub
System.out.println("....b1....");
}
}
//结果:
//....b1....
抽象类的应用:
从对象多态性的概念上来看,子类为父类实例化是一个比较容易的操作,因为可以发生自动的向上转型关系,那么调用方法永远是呗子类覆写过的方法。
那么,此时可以利用此概念通过对象多态性为抽象类实例化
abstract class AbstractDemoA{
public abstract void fun1();
}
class AbstractDemoB extends AbstractDemoA{
public void fun1(){
System.out.println("———abstractDemoB—————");
}
}
public class AbstractDemo1 {
public static void main(String args[]){
AbstractDemoA abstractDemoA = new AbstractDemoB();
abstractDemoA.fun1();
}
}
//结果:
//———abstractDemoB—————
例子:
例如:人分为两种:工人和学生
*假设工人和学生都有姓名和年龄属性,但是工人有工资,学生有成绩
*工人和学生都可以说话,但是说话的内容不一样
package com.demo;
abstract class Person {
private String name;
private String age;
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
public void say(){
sayContent();
}
public abstract void sayContent();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class Student extends Person{
private float score;
public Student(String name, String age,float score) {
super(name, age);
this.score = score;
// TODO Auto-generated constructor stub
}
@Override
public void sayContent() {
// TODO Auto-generated method stub
System.out.println("I'm a student"+" socre="+score);
}
}
class Worker extends Person{
public Worker(String name, String age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@Override
public void sayContent() {
// TODO Auto-generated method stub
System.out.println("I'm a work");
}
}
public class PersonDemo {
public static void main(String args[]){
Person person1 = new Student("zhang san", "11", 100);
Person person2 = new Worker("李四", "30");
person1.say();
person2.say();
}
}
//结果:
//I'm a student socre=100.0
//I'm a work
在java中使用interface定义一个接口
1、接口需要有子类,子类实现接口,通过implements关键字完成
2、可以简化如例子
3、一个类只能继承一个父类,但是可以实现多个接口
4、如果一个类既要实现接口又要继承抽象类,则必须按照以下形式完成
class 子类 extends 抽象类 implements 接口A,接口B....
5、一个抽象类可以实现多个接口,但是一个接口不能继承一个抽象类
6、一个接口不可以继承一个抽象类,但是可以同时继承多个接口
例子:
interface InterfaceDemo1 {
public static String NAME = "INTERFACE_DEMO";//也可以写成 String NAME = "INTERFACE_DEMO";
public abstract void fun1();//一般写成 public void fun1(); 也可以写成 void fun1();
public abstract void fun2();//一般写成 public void fun2(); 也可以写成 void fun2();
}
class InterfaceDemo2 implements InterfaceDemo1 {
@Override
public void fun1() {
// TODO Auto-generated method stub
System.out.println("----fun1---");
}
@Override
public void fun2() {
// TODO Auto-generated method stub
System.out.println("---fun2---" + NAME);
}
}
public class InterfaceDemo {
public static void main(String args[]) {
InterfaceDemo2 interfaceDemo2 = new InterfaceDemo2();
interfaceDemo2.fun1();
interfaceDemo2.fun2();
}
}
// 结果:
// ----fun1---
// ---fun2---INTERFACE_DEMO
接口的应用:
接口也可以像抽象类那样通过对象多态性进行对象实例化操作
接口实际上是作为一个标准存在的;
例如:电脑上实现了USB接口,U盘,打印机也都实现了
package com.demo;
interface Usb{
public void start(); //开始工作
public void stop(); //停止工作
}
class Computer{
public void connect(Usb usb){
usb.start();
usb.stop();
}
}
class Upan implements Usb{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("U盘。。。开始工作");
}
@Override
public void stop() {
// TODO Auto-generated method stub
System.out.println("U盘。。。。停止工作");
}
}
class Print implements Usb{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("打印机。。。开始工作");
}
@Override
public void stop() {
// TODO Auto-generated method stub
System.out.println("打印机。。。。停止工作");
}
}
public class InterfaceDemo {
public static void main(String args[]){
Upan upan = new Upan();
Print print = new Print();
Computer computer = new Computer();
computer.connect(upan);
computer.connect(print);
}
}
//结果:
//U盘。。。开始工作
//U盘。。。。停止工作
//打印机。。。开始工作
//打印机。。。。停止工作
接口和抽象类:
适配器设计模式:
接口的子类要实现全部抽象类的方法
但是如过希望可以根据自己的需要来选择性的覆写,那么应该用一个类(抽象类),先将接口实现了,但是所有的方法都属于空实现,之类再继承此类
package com.demo;
public class AdapterDemo {
public static void main(String args[]){
Windows window = new MyWindow();
window.open();
window.close();
}
}
/**
*窗口接口
*/
interface Windows{
public void open(); //打开窗口
public void close();//关闭窗口
public void icon();//最小化
public void unicon();//最大化
}
/**
* 窗口适配器
*/
abstract class WindowsAdapter implements Windows{
@Override
public void open() {};
@Override
public void close() {
System.out.println("关闭窗口 ---->close");
};
@Override
public void icon() {};
@Override
public void unicon() {};
}
/**
* 具体的窗口类
*/
class MyWindow extends WindowsAdapter{
@Override
public void open() {
// TODO Auto-generated method stub
super.open();
System.out.println("打开窗口----->open");
}
}
//结果:
//打开窗口----->open
//关闭窗口 ---->close
工厂设计模式:
所有接口的实例化对象都是通过工厂类取得的,那么客户端调用的时候根据传入的名称不同,完成的功能也不同。
package com.demo;
import java.util.Scanner;
public class FactoryDemo {
public static void main(String args[]) {
while (true) {
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
if (name.equals("exit")) {
break;
}
Fruit f = Factory.getFruit(name);
if (null != f) {
f.eat();
}
}
}
}
interface Fruit {
public void eat();
}
class Apple implements Fruit {
@Override
public void eat() {
System.out.println("吃苹果");
}
}
class Orange implements Fruit {
@Override
public void eat() {
System.out.println("吃橘子");
}
}
class Factory {// 工厂类
public static Fruit getFruit(String name) {
Fruit f = null;
if ("apple".equals(name)) {
f = new Apple();
}
if ("orange".equals(name)) {
f = new Orange();
}
return f;
}
}
所有接口的实例化对象都是通过工厂类取得的。那么客户端调用的时候根据传入的名称不同,完成的功能也不同。
if("orange".equles(className)){
f = new Orange();
}
在以上程序中将字符串写在前面,通过字符串的匿名对象调用方法。
代理设计模式:
现在有如下一种情况,生活情况
例如:张三属于老好人,有钱,之后李四向张阳借了 10000元钱,规定一年还
- 一年之后张三向李四讨债的时候李四不还
- 张三无奈之下找到王五,王五经营一家讨债公司,基本首付:刀子、手枪
- 王五为了成功的把钱讨回来,准备好了 小刀、绳子、手枪
- 李四害怕王五,还钱了
- 王五为了不让李四起诉 销毁了所有的罪证
package com.demo;
public class ProxyMode {
public static void main(String args[]){
DaiLi daiLi = new DaiLi(new ZhaiZhu());
daiLi.giveBack();
}
}
/**
* 主要内容:讨债
*/
interface TaoZhai{
public void giveBack();
}
/**
* 债主:张三
*/
class ZhaiZhu implements TaoZhai{
@Override
public void giveBack() {
System.out.println("请把我的钱还给我");
}
}
/**
* 代理讨债的人:王五
*/
class DaiLi implements TaoZhai{
private TaoZhai taoZhai;
public DaiLi(TaoZhai taoZhai) {
super();
this.taoZhai = taoZhai;
}
/**
* 讨债之前的准备
*/
public void geiBackBefore(){
System.out.println("小刀、绳子、手枪");
}
/**
* 讨债事件
*/
@Override
public void giveBack() {
// TODO Auto-generated method stub
geiBackBefore();
this.taoZhai.giveBack();
geiBackAfter();
}
/**
* 讨债之后善后
*/
public void geiBackAfter(){
System.out.println(" 销毁了所有的罪证");
}
}
//结果:
//小刀、绳子、手枪
//请把我的钱还给我
// 销毁了所有的罪证
抽象类和接口的区别:
抽象类和接口同时可以使用的话,优先使用接口,因为接口可以避免单继承的局限
No | 比较点 | 抽象类 | 接口 |
1 | 组成 | 抽象方法、普通方法、常量、变量、构造方法、全局常量 | 抽象方法、全局变量 |
2 | 定义 | abstract | interface |
3 | 子类 | 子类通过extends继承抽象类 | 子类通过implements实现接口 |
4 | 限制 | 一个子类只能继承一个抽象类 | 一个子类可以同时实现多个接口 |
5 | 关系 |
|
|
6 | 设计模式 | 模版设计 | 工厂设计、代理设计 |
抽象类和接口一起可以 | 完成适配器设计 | ||
7 | 实例化 | 都是通过对象的多态性,通过 | 子类进行对象的实例化 |
8 | 实现限制 | 存在单继承局限 | 不存在此局限 |
9 | 特性 | 表示一个标准、一种能力 |