JavaSE_day15:面向对象(下)
面向对象(下)
- 1. 关键字:abstract
- 2. 抽象类的匿名子类
- 3. 模板方法的设计模式
- 4. 接口interface
- 4.1 接口例子:USBTest.java
- 4.2 接口匿名实现类的对象
- 5. 接口的应用
- 5.1 代理模式
- 5.2 工厂模式
- 6. Java8接口新特性
- 7. 类的结构:内部类
1. 关键字:abstract
作用:用来修饰类、方法
1.1 abstract修饰类:抽象类
此类不能实例化
抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 —>抽象的使用前提:继承性
1.2 abstract修饰方法:抽象方法
抽象方法只方法的声明,没方法体 (不能
new)
包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
若子类重写了父类中的所的抽象方法后,此子类方可实例化
若子类没重写父类中的所的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
1.3 注意点:
abstract 不能用来修饰:属性、构造器等结构
abstract 不能用来修饰:私方法、静态方法、final的方法、final的类
举例1:AbstractTest.java
public class AbstractTest {public static void main(String[] args) {//一旦Person类抽象了,就不可实例化
// Person p1 = new Person();
// p1.eat(); }
}
abstract class Creature{public abstract void breath();
}
abstract class Person extends Creature{String name;int age;public Person(){}public Person(String name,int age){this.name = name;this.age = age;}//不是抽象方法:
// public void eat(){
//
// }//抽象方法public abstract void eat();public void walk(){System.out.println("人走路");}
}
class Student extends Person{public Student(String name,int age){super(name,age);}public Student(){}public void eat(){System.out.println("学生多吃有营养的食物");}@Overridepublic void breath() {System.out.println("学生应该呼吸新鲜的没有雾霾的空气");}
}
举例2:
//抽象类
public abstract class Vehicle{public abstract double calcFuelEfficiency(); //计算燃料效率的抽象方法public abstract double calcTripDistance(); //计算行驶距离的抽象方法
}
//子类Truck
public class Truck extends Vehicle{public double calcFuelEfficiency( ) { //写出计算卡车的燃料效率的具体方法 }public double calcTripDistance( ) { //写出计算卡车行驶距离的具体方法 }
}
//子类RiverBarge
public class RiverBarge extends Vehicle{public double calcFuelEfficiency( ) { //写出计算驳船的燃料效率的具体方法 }public double calcTripDistance( ) { //写出计算驳船行驶距离的具体方法}
}
举例3:IO流中设计到的抽象类:InputStream/OutputStream/Reader/Writer。在其内部
定义了抽象的read()、write()方法。
2. 抽象类的匿名子类
PersonTest.java的类涉及到AbstractTest.java的类:Person
public class PersonTest {public static void main(String[] args) {method(new Student()); // 匿名对象Worker worker = new Worker();method1(worker); // 非匿名的类非匿名的对象method1(new Worker());// 非匿名的类匿名的对象System.out.println("************************************");// 创建了一匿名子类的对象:p;左边new Person(){...};是Person的子类Person p = new Person() {@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("吃东西");}@Overridepublic void breath() {// TODO Auto-generated method stubSystem.out.println("好好呼吸");}};method1(p);System.out.println("************************************");// 创建匿名子类的匿名对象method1(new Person() {@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("吃好的东西");}@Overridepublic void breath() {// TODO Auto-generated method stubSystem.out.println("好好呼吸新鲜的空气");}});}// 多态的使用public static void method1(Person p) {p.eat();p.breath();}public static void method(Student s) {}
}class Worker extends Person {@Overridepublic void eat() {// TODO Auto-generated method stub}@Overridepublic void breath() {// TODO Auto-generated method stub}}
3. 模板方法的设计模式
源码会涉及该部分内容,要看得懂源码写法。
解决的问题:
在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。
例:计算某段代码执行所需要花费的时间
/** 抽象类的应用:模板方法的设计模式*/
public class TemplateTest {public static void main(String[] args) {SubTemplate t = new SubTemplate();t.spendTime();}
}
abstract class Template{//计算某段代码执行所需要花费的时间public void spendTime(){long start = System.currentTimeMillis();this.code();//不确定的部分、易变的部分long end = System.currentTimeMillis();System.out.println("花费的时间为:" + (end - start));}public abstract void code();
}class SubTemplate extends Template{@Overridepublic void code() {for(int i = 2;i <= 1000;i++){boolean isFlag = true;for(int j = 2;j <= Math.sqrt(i);j++){if(i % j == 0){isFlag = false;break;}}if(isFlag){System.out.println(i);}}}
}
例:银行简单的办理业务
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {public static void main(String[] args) {BankTemplateMethod btm = new DrawMoney();btm.process();BankTemplateMethod btm2 = new ManageMoney();btm2.process();}
}
abstract class BankTemplateMethod {// 具体方法public void takeNumber() {System.out.println("取号排队");}public abstract void transact(); // 办理具体的业务 //钩子方法public void evaluate() {System.out.println("反馈评分");}// 模板方法,把基本操作组合到一起,子类一般不能重写public final void process() {this.takeNumber();this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码this.evaluate();}
}class DrawMoney extends BankTemplateMethod {public void transact() {System.out.println("我要取款!!!");}
}
class ManageMoney extends BankTemplateMethod {public void transact() {System.out.println("我要理财!我这里有2000万美元!!");}
}

4. 接口interface
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。继承是一个"是不是"的关系,而接口实现则是 "能不能"的关系。
接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。
有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
1.接口使用interface来定义
2.Java中,接口和类是并列的两个结构
3.如何定义接口:定义接口中的成员
JDK7及以前:只能定义全局常量和抽象方法
全局常量:public static final的.但是书写时,可以省略不写
抽象方法:public abstract的
JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
4.接口中不能定义构造器的!意味着接口不可以实例化
5.Java开发中,接口通过让类去实现(implements)的方式来使用.
- 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
- 如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
6.Java类可以实现多个接口 —>弥补了Java单继承性的局限性
- 格式:
class AA extends BB implements CC,DD,EE

7.接口与接口之间可以继承,而且可以多继承
8. 接口的具体使用,体现多态性
9. 接口,实际上可以看做是一种规范
例子:InterfaceTest.java

public class InterfaceTest {public static void main(String[] args) {System.out.println(Flyable.MAX_SPEED);System.out.println(Flyable.MIN_SPEED);
// Flyable.MIN_SPEED = 2; //final 修饰为常量,不能再赋值Plane plane = new Plane();plane.fly();}
}interface Flyable{//全局常量public static final int MAX_SPEED = 7900;//第一宇宙速度int MIN_SPEED = 1;//省略了public static final//抽象方法public abstract void fly();//省略了public abstractvoid stop();//Interfaces cannot have constructors
// public Flyable(){
//
// }
}
interface Attackable{void attack();
}class Plane implements Flyable{@Overridepublic void fly() {System.out.println("通过引擎起飞");}@Overridepublic void stop() {System.out.println("驾驶员减速停止");}
}
//没有实现接口的所有的方法,则实现类也是抽象的
abstract class Kite implements Flyable{@Overridepublic void fly() {}
}class Bullet extends Object implements Flyable,Attackable,CC{@Overridepublic void attack() {// TODO Auto-generated method stub}@Overridepublic void fly() {// TODO Auto-generated method stub}@Overridepublic void stop() {// TODO Auto-generated method stub}@Overridepublic void method1() {// TODO Auto-generated method stub}@Overridepublic void method2() {// TODO Auto-generated method stub}}
//************************************
interface AA{void method1();
}
interface BB{void method2();
}
//接口和接口可以继承,且可多继承
interface CC extends AA,BB{
}
4.1 接口例子:USBTest.java

/** 接口的使用* 1.接口使用上也满足多态性* 2.接口,实际上就是定义了一种规范* 3.开发中,体会面向接口编程!*/
public class USBTest {public static void main(String[] args) {Computer com = new Computer();Flash flash = new Flash();com.transferData(flash);}
}class Computer {public void transferData(USB usb) {// USB usb = new Flash();usb.start();System.out.println("具体传输数据的细节");usb.start();}
}interface USB {// 常量:定义了长、宽、最大最小的传输速度等void start();void stop();
}class Flash implements USB {@Overridepublic void start() {System.out.println("U盘开启工作");}@Overridepublic void stop() {System.out.println("U盘结束工作");}
}class Printer implements USB {@Overridepublic void start() {System.out.println("打印机开启工作");}@Overridepublic void stop() {System.out.println("打印机结束工作");}
}
4.2 接口匿名实现类的对象
public class USBTest {public static void main(String[] args) {Computer com = new Computer();//1.创建了接口的非匿名实现类的非匿名对象Flash flash = new Flash();com.transferData(flash);//2. 创建了接口的非匿名实现类的匿名对象com.transferData(new Printer());//3. 创建了接口的匿名实现类的非匿名对象USB phone = new USB(){@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop() {System.out.println("手机结束工作");} };com.transferData(phone);//4. 创建了接口的匿名实现类的匿名对象com.transferData(new USB(){@Overridepublic void start() {System.out.println("mp3开始工作");}@Overridepublic void stop() {System.out.println("mp3结束工作");}});}
}class Computer{public void transferData(USB usb){//USB usb = new Flash();usb.start();System.out.println("具体传输数据的细节");usb.stop();}
}interface USB{//常量:定义了长、宽、最大最小的传输速度等void start();void stop();
}class Flash implements USB{@Overridepublic void start() {System.out.println("U盘开启工作");}@Overridepublic void stop() {System.out.println("U盘结束工作");}
}
class Printer implements USB{@Overridepublic void start() {System.out.println("打印机开启工作");}@Overridepublic void stop() {System.out.println("打印机结束工作");}
}

5. 接口的应用
5.1 代理模式
代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问。( 会懂得代思想即可。)
例子1:
/** 接口的应用:代理模式* */
public class NetWorkTest {public static void main(String[] args) {Server server = new Server();
// server.browse();ProxyServer proxyServer = new ProxyServer(server);proxyServer.browse(); }
}interface NetWork{public void browse();
}//被代理类
class Server implements NetWork{@Overridepublic void browse() {System.out.println("真实的服务器访问网络");}
}
//代理类
class ProxyServer implements NetWork{private NetWork work;public ProxyServer(NetWork work){this.work = work;}public void check(){System.out.println("联网之前的检查工作");}@Overridepublic void browse() {check();work.browse();}
}
例子2:
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("经纪人收钱");}
}
5.2 工厂模式
解决的问题
实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
具体模式
简单工厂模式:用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)
工厂方法模式:用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂模式:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
6. Java8接口新特性
1.SubClassTest.java
public class SubClassTest {public static void main(String[] args) {SubClass s = new SubClass();// s.method1();
// SubClass.method1();//知识点1:接口中定义的静态方法,只能通过接口来调用。CompareA.method1();//知识点2:通过实现类的对象,可以调用接口中的默认方法。//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法s.method2();//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,//那么在实现类没有重写此方法的情况下,报错。-->接口冲突。//这就需要我们必须在实现类中重写此方法s.method3();}
}class SubClass extends SuperClass implements CompareA,CompareB{public void method2(){System.out.println("SubClass:上海");}public void method3(){System.out.println("SubClass:深圳");}//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法public void myMethod(){method3();//调用自己定义的重写的方法super.method3();//调用的是父类中声明的//调用接口中的默认方法CompareA.super.method3();CompareB.super.method3();}
}
2.接口CompareA.java
public interface CompareA {//静态方法public static void method1(){System.out.println("CompareA:北京");}//默认方法public default void method2(){System.out.println("CompareA:上海");}default void method3(){System.out.println("CompareA:上海");}
}
3.接口CompareB.java
public interface CompareB {default void method3(){System.out.println("CompareB:上海");}
}
4.父类SuperClass.java
public class SuperClass {public void method3(){System.out.println("SuperClass:北京");}
}
7. 类的结构:内部类
Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类.
分类:
成员内部类(静态、非静态 ) vs 局部内部类(方法内、代码块内、构造器内)
成员内部类:
1.外部类的成员
- 调用外部类的结构
- 可以被
static修饰 - 可以被4种不同的权限修饰
2.作为一个类
- 类内可以定义属性、方法、构造器等
- 可以被
final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承 - 可以被
abstract修饰
例子 InnerClassTest.java
public class InnerClassTest {public static void main(String[] args) {//创建Dog实例(静态的成员内部类):Person.Dog dog = new Person.Dog();dog.show();//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的Person p = new Person();Person.Bird bird = p.new Bird();bird.sing();System.out.println();bird.display("黄鹂");}
}
class Person{String name = "小明";int age;public void eat(){System.out.println("人:吃饭");}//静态成员内部类static class Dog{String name;int age;public void show(){System.out.println("卡拉是条狗");
// eat();}}//非静态成员内部类class Bird{String name = "杜鹃";public Bird(){}public void sing(){System.out.println("我是一只小小鸟");Person.this.eat();//调用外部类的非静态属性eat();//没有重名就直接调用Person的ageSystem.out.println(age);}public void display(String name){System.out.println(name);//方法的形参System.out.println(this.name);//内部类的属性System.out.println(Person.this.name);//外部类的属性}}public void method(){//局部内部类class AA{}}{//局部内部类class BB{ }}public Person(){//局部内部类class CC{ }}
}
开发中使用内部类:
public class InnerClassTest1 {//开发中很少见public void method(){//局部内部类class AA{}}//返回一个实现了Comparable接口的类的对象public Comparable getComparable(){//创建一个实现了Comparable接口的类:局部内部类//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();//方式二:return new Comparable(){@Overridepublic int compareTo(Object o) {return 0;}};}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
