347 抽象类的课后练习
public abstract class Employee{
private String name;
private int number;
private MyDate birthday;
public Employee(String name, int number, MyDate birthday) {
super();
this.name = name;
this.number = number;
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
public abstract double earnings();
public abstract void earnings();
public String toString(){
return "Employee [name="+name+",number="+number+",birthday="+birthday.toDateString()+"]";
}
public class MyDate{
private int year;
private int month;
private int day;
public MyDate(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String toDateString(){
return year+"年"+month+"月"+day+"日";
}
}
public class SalariedEmployee extends Employee{
private double monthlySalary;
public SalariedEmployee(String name,int number,MyDate birthday){
super(name,number,birthday);
}
public SalariedEmployee(String name,int number,MyDate birthday,double monthlySalary){
super(name,number,birthday);
this.monthlySalary=monthlySalary;
}
public double earnings(){
return monthlySalary;
}
public String toString(){
return "SalariedEmployee["+super.toString()+"]";
}
}
public class HourlyEmployee extends Employee{
private int wage;//每小时的工资
private int hour;//月工作的小时数
public HourlyEmployee(String name,int number,MyDate birthday){
super(name,number,birthday);
}
public HourlyEmployee(String name,int number,MyDate birthday,int wage,int hour){
super(name,number,birthday);
this.wage=wage;
this.hour=hour;
}
public int getWage(){
return wage;
}
public void setWage(int wage){
this.wage=wage;
}
public int getHour(){
return hour;
}
public void setHour(int hour){
this.hour=hour;
}
public double earnings(){
return wage*hour;
}
public String toString(){
return "HourlyEmployee["+super.toString()+"]";
}
}
public class PayrollSystem{
public static void main(String[] args){
//方式一
Scanner scanner=new Scanner(System.in);
System.out.println("请输入当月的月份");
int month=scanner.nextInt();
//方式二
Calendar calendar=Calendar.getInstance();
int month=calendar.get(Calendar.MONTH);
Employee[] emps=new Employee[2];
emps[0]=new SalariedEmployee("马森",1002,new MyDate(1992,2,28),10000);
emps[1]=new HourlyEmployee("潘雨生",2001,new MyDate(1991,1,6),60,240);
for(int i=0;i<emps.length;i++){
System.out.println(emps[i]);
double salary=emps[i].earnings();
System.out.println("月工资为:"+salary);
if(month+1==emps[i].getBirthday().getMonth()){
System.out.println("生日快乐!奖励100元");
}
}
}
}
348 接口的理解
一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果。
另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有 is-a 的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3 机、手机、数码相机、移动硬盘等都支持 USB 连接。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。
接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。
349 接口的定义和使用
1.接口使用interface来定义
2.在Java中,接口和类是并列的两个结构
3.如何定义接口:定义接口中的成员
3.1 jdk7之前:只能定义全局常量和抽象方法
全局常量:public static final的,但是可以省略不写
抽象方法:public abstract
3.2 jdk8:除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法
4.接口中不能定义构造器,意味着接口不可以实例化
5.java开发中,接口通过让类去实现(implements)的方式来使用
如果实现类覆盖了接口中所有的抽象方法,则此实现类就可以实例化
如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍然是一个抽象类
public class InterfaceTest{
public static void main(String[] args){
Plane plane=new Plane();
plane.fly();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED=7900;//第一宇宙速度
public static final int MIN_SPEED=1;
//抽象方法
public abstrct void fly();
void stop;
}
interface Attackable{
void attack();
}
class Plane implements Flyable{
public void fly(){
System.out.println("通过引擎起飞");
}
public void stop(){
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
public void fly(){
}
}
class Bullet extends Object implements Flyable,Attachable,CC{
public void attack(){
}
public void stop(){
}
public void fly(){
}
public void method1(){
}
public void method2(){
}
}
interface AA{
void method1();
}
interface BB{
void method2();
}
interface CC extends AA,BB{
}
350 接口的多实现与接口的继承性
6.java类可以实现多个接口----弥补了java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE
7.接口与接口之间可以继承,并且可以多继承
8.接口的具体使用,体现多态性
9.接口,实际上可以看做是一种规范
351 实例演示接口是一种规范
public class USBTest{
public static void main(String[] args){
Computer com=new Compuer();
//1.创建了接口的非匿名实现类的非匿名对象
Flash flash=new Flash();
com.transferData(flash);
//2.创建了接口的非匿名实现类的匿名对象
com.transferData(new Printer());
//3.创建了接口的匿名实现类的非匿名对象
USB phone=new USB(){
public void start(){
System.out.println("手机开始工作");
}
public void stop(){
System.out.println("手机结束工作");
}
};
com.transferData(phone);
//4.创建了接口的匿名实现类的匿名对象
com.transferData(new USB(){
public void start(){
System.out.println("mp3开始工作");
}
public void stop(){
System.out.println("mp3结束工作");
}
});
}
}
class Computer{
public void transferData(USB usb){
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB{
//常量,定义了长,宽,最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB{
public void start(){
System.out.println("U盘开启工作")
}
public void stop(){
System.out.println("U盘结束工作")
}
}
class Printer implements USB{
public void start(){
System.out.println("打印机开启工作")
}
public void stop(){
System.out.println("打印机结束工作")
}
}
接口的使用
1.接口使用上也满足多态性
2.接口,实际上就是定义了一种规范
3.开发中体会面向接口编程
352 创建接口匿名实现类的对象
353 接口应用:代理模式
代理模式是 Java 开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问。
public class NetWorkTest{
public static void main(String[] args){
Server server=new Server();
new ProxyServer(server);
proxyServer.browse();
}
}
interface NetWork{
public void browse();
}
//被代理类
class Server implements NetWork{
public void browse(){
System.ou.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work){
this.work=work;
}
public void check(){
System.ou.println("联网之前的检查工作");
}
public void browse(){
check();
work.browse();
}
}
应用场景:
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(RMI)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有 100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用 proxy 来进行大图片的打开。
分类
静态代理(静态定义代理类)
动态代理(动态生成代理类)
JDK 自带的动态代理,需要反射等知识
public class StaticProxyTest {
public static void main(String[] args) {
Proxy s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面谈
void signContract();// 签合同
void bookTicket();// 订票
void sing();// 唱歌
void collectMoney();// 收钱
}
//被代理类
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
//代理类
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
354 接口应用:工厂模式
355 接口课后两道笔试题
接口和抽象类之间的对比
No. 区别点 抽象类 接口
1 定义 包含抽象方法的类 主要是抽象方法和全局常量的集合
2 组成 构造方法、抽象方法、普通方法、常量、变量 常量、抽象方法、(jdk8.0:默认方法、静态方法)
3 使用 子类继承抽象类(extends) 子类实现接口(implements)
4 关系 抽象类可以实现多个接口 接口不能继承抽象类,但允许继承多个接口
5 常见设计模式 模板方法 简单工厂、工厂方法、代理模式
6 对象 都通过对象的多态性产生实例化对象
7 局限 抽象类有单继承的局限 接口没有此局限
8 实际 作为一个模板 是作为一个标准或是表示一种能力
9 选择 如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
// 编译不通过,x 不明确
System.out.println(x);
// System.out.println(super.x); //1
// System.out.println(A.x);//0
}
public static void main(String[] args) {
new C().pX();
}
}
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable, Bounceable {
Ball ball= new Ball("PingPang"); //省略了 public static final
}
public class Ball implements Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name= name;
}
public void play() {
ball = new Ball("Football"); //The final field Rollable.ball cannot be assigned
System.out.println(ball.getName());
}
}