回顾
13.2.3 接口的作用——制定标准
13.2.4 接口的作用——工厂设计模式(Factory)
学习小结
13.2.5 接口的作用——代理设计模式(Proxy)
代理模式:给某一对像提供代理对象,并由代理对象控制具体对象的引用。
范例:
package com.Javastudy2;
/**
* @author Y.W.
* @date 2018年2月28日 下午10:33:09
* @Description TODO 代理设计模式
*/
public class P344_13_13 {
public static void main(String[] args) { // 客户直接找代理商
Subject sub = new ProxySubject(); // 子类为接口实例化
sub.request();
}
}
abstract class Subject { // 代理请求
abstract public void request();
}
class RealSubject extends Subject { // 真实角色(厂商)
@Override
public void request() { // 覆写抽象方法
System.out.println("我是厂商,欢迎购买。");
}
}
class ProxySubject extends Subject { // 代理角色(代理商)
private RealSubject realSubject; // 以真实角色作为代理角色的属性
public void request() { // 该方法封装了真实对象的request方法
preRequest();
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request(); // 此处执行真实对象的方法
postRequest();
}
private void preRequest() {
System.out.println("广告");
// something you want to do before requesting
}
private void postRequest() {
System.out.println("付款购买");
// something you want to do after requesting
}
}
运行结果:
运行结果
13.3 抽象类和接口对比
抽象类和接口对比
抽象类和接口的共同点:
否是抽象类型;
都可以有实现方法;
都可以不需要实现类或者继承者去实现所有方法。
抽象类和接口不同点:
抽象类不可以多重继承,接口可以(无论是多重类型继承还是多重行为继承);
抽象类和接口所反映出的设计理念不同。抽象类表示“is-a”关系,接口表示的是“like-a”关系;
接口中定义的变量默认是public static final型,且必须给其赋初值,所以类中不能重新定义和改值;抽象类中的变量默认是friendly型,其值可在子类中重新定义和重新赋值。
13.4 点拨
1.继承抽象类和继承普通类的主要区别
普通类里的是含方法体的方法,子类可以覆写也可以不覆写。
抽象类里的是抽象方法,子类必须覆写。
- 接口、抽象类、类、对象的关系
接口、抽象类、类、对象的关系
习题
- 设计一个限制子类的访问的抽象类实例,要求在控制台输出如下结果。
教师 → 姓名:刘三,年龄:50,职业:教师
工人 → 姓名:赵四,年龄:30,职业:工人
package com.Javastudy2;
/**
* @author Y.W.
* @date 2018年2月28日 下午11:42:13
* @Description TODO 设计一个限制子类的访问的抽象类实例,要求在控制台输出如下结果。 教师 → 姓名:刘三,年龄:50,职业:教师 工人 →
* 姓名:赵四,年龄:30,职业:工人
*/
public class P350_13_5_1_ok {
public static void main(String[] args) {
Teacher t = new Teacher("刘三", 50, "教师"); // 创建Teacher类对象t
Workman w = new Workman("李四", 30, "工人"); // 创建Workman类对象w
System.out.println(t.talk()); // 调用被覆写的方法
System.out.println(w.talk());
}
}
abstract class People { // 定义一个抽象类People
String name;
int age;
String occupation;
public abstract String talk(); // 声明一个抽象方法talk()
}
class Teacher extends People { // Teacher类继承自People类
public Teacher(String name, int age, String occupation) {
this.name = name;
this.age = age;
this.occupation = occupation;
}
public String talk() { // 覆写抽象方法talk()
return "教师--》姓名:" + this.name + ",年龄:" + this.age + ",职业:" + this.occupation + "!";
}
}
class Workman extends People { // Workman类继承自People类
public Workman(String name, int age, String occupation) {
this.name = name;
this.age = age;
this.occupation = occupation;
}
public String talk() { // 覆写抽象方法talk()
return "工人--》姓名:" + this.name + ",年龄:" + this.age + ",职业:" + this.occupation + "!";
}
}
运行结果:
运行结果
- 利用接口及抽象类设计实现
(1)定义接口圆形CircleShape(),其中定义常量PI,默认方法area计算园面积;
(2)定义圆形类Circle实现接口CircleShape,包含构造方法和求圆周长方法;
(3)定义圆柱继承Circle实现接口CircleShape,包含构造方法,圆柱表面积,体积;
(4)从控制台输入圆半径,输出圆面积及周长;
(5)从控制台输入圆柱底面半径及高,输出圆柱底面积、圆柱表面积及体积。
package com.Javastudy2;
import java.util.Scanner;
/**
* @author Y.W.
* @date 2018年3月1日 上午12:27:18
* @Description TODO 利用接口及抽象类设计实现 (1)定义接口圆形CircleShape(),其中定义常量PI,默认方法area计算园面积;
* (2)定义圆形类Circle实现接口CircleShape,包含构造方法和求圆周长方法;
* (3)定义圆柱继承Circle实现接口CircleShape,包含构造方法,圆柱表面积,体积;
* (4)从控制台输入圆半径,输出圆面积及周长; (5)从控制台输入圆柱底面半径及高,输出圆柱底面积、圆柱表面积及体积。
*/
public class P350_13_5_2 {
public static void main(String[] args) {
double r = 0;
double h = 0;
Scanner input = new Scanner(System.in);
System.out.println("请输入圆半径r1(数字):");
while (input.hasNext()) {
String s1 = input.next();
try {
r = Double.parseDouble(s1);
} catch (NumberFormatException e) {
System.out.println("请重新输入数字:");
continue;
}
break;
}
Circle circle = new Circle(r);
System.out.println("圆面积:" + circle.area(r));
System.out.println("圆周长:" + circle.perimeter());
System.out.println("请输入圆柱底面半径r2(数字):");
while (input.hasNext()) {
String s2 = input.next();
try {
r = Double.parseDouble(s2);
} catch (NumberFormatException e) {
System.out.println("请重新输入数字:");
continue;
}
break;
}
System.out.println("请输入圆柱高h(数字):");
while (input.hasNext()) {
String s3 = input.next();
try {
h = Double.parseDouble(s3);
} catch (NumberFormatException e) {
System.out.println("请重新输入数字:");
continue;
}
break;
}
Cylinder cylinder = new Cylinder(r, h);
System.out.println("圆柱底面积:" + cylinder.area(r));
System.out.println("圆柱表面积:" + cylinder.cylinderArea());
System.out.println("圆柱体积:" + cylinder.cylinderCubage());
}
}
interface CircleShape {
public static final double PI = 3.14;
default public double area(double r) { // 圆面积
return r * r * PI;
}
}
class Circle implements CircleShape {
double r;
public double perimeter() { // 圆周长
return 2 * PI * r;
}
public Circle(double r) { // 构造方法
this.r = r;
}
}
class Cylinder extends Circle implements CircleShape {
double h;
public Cylinder(double r, double h) { // 构造方法
super(r);
this.h = h;
}
public double cylinderArea() { // 圆柱表面积
return perimeter() * h + area(r);
}
public double cylinderCubage() { // 圆柱体积
return h * area(r);
}
}
运行结果:
运行结果
思考
还有一个问题,下次查原因吧
问题