抽象类
动物具体移动方式没法在动物类中去写,所有动物类和其方法都是抽象化处理,就不写具体的实现。
- 用abstract关键字修饰一个类时,这个类叫做抽象类。
- 用abstract关键字修饰一个方法时,这个方法叫做抽象方法。
- 不能被实例化
- 只要类中有一个抽象的方法,那么这个类就必须是一个抽象类
public abstract class Animal {
public abstract void move();
}
class Dog extends Animal {
@Override
public void move() {
System.out.println("狗的移动方式是跑");
}
}
class Fish extends Animal {
@Override
public void move() {
System.out.println("鱼的移动方式是游");
}
}
abstract class Bird extends Animal {
@Override
public void move() {
}
public abstract void test(); //只要类中有一个抽象方法,类就必须是一个抽象类
}
问题1:为什么抽象类不可以使用final关键字声明?
final是最终,他修饰的类不能被继承;而抽象类是用来被继承的,子类必须重写父类的抽象方法,并且提供方法体。
问题2:一个抽象类中可以定义构造器吗?
抽象类可以有构造方法,但不能实例化。
public abstract class Employee {
int id;
String name;
double salary;
public abstract void work();
}
class Manager extends Employee{
double bonus;
public void setManager(int id, String name, double salary, double bonus) {
super.id = id; //从父类继承的属性,用super
super.name = name;
super.salary = salary;
this.bonus = bonus; //本类自己的属性,用this
}
public void getManager() {
System.out.println(super.id);
System.out.println(super.name);
System.out.println(super.salary);
System.out.println(this.bonus);
}
@Override
public void work() {
System.out.println("这是领导");
}
}
class CommonEmployee extends Employee{
public void setCommonEmployee(int id, String name, double salary) {
super.id = id;
super.name = name;
super.salary = salary;
}
public void getCommonEmployee() {
System.out.println(super.id);
System.out.println(super.name);
System.out.println(super.salary);
}
@Override
public void work() {
System.out.println("这是员工");
}
}
模板方法设计模式
抽象类就像一个大纲,里面的抽象方法就是每个章节的标题,子类,去根据这些标题把每个章节细化出来。
public abstract class Template {
public abstract void code();
public final void getTime() {
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("code方法执行的时间:" + (end - start));
}
}
class TestTemplate extends Template {
int k = 0;
@Override
public void code() {
for (int i = 0; i < 50000; i++) {
k += 1;
}
}
}
接口(interface)
抽象方法和常量值的定义的集合。
- 从本质上讲,接口是一种特殊的抽象类,只包含常量和方法的定义,而没有变量和方法的实现。
- 实现接口类:implements
- 一个类可以实现多个接口,接口也可以继承其他接口。
接口的特点:
- 用interface来定义
- 接口中的所有成员变量都默认是由public static final修饰的
- 接口中的所有方法都默认是由public abstract修饰的
- 接口没有构造器
- 接口采用多重继承机制
例子:用java描述会唱歌的厨子是个老师。
public abstract class Person1 {
int age;
String name;
String sex;
public abstract void showInfo();
}
public interface Cooking {
void fry();
}
public interface Singer {
void sing();
}
public class SCTeacher extends Person1 implements Cooking, Singer {
String course; //教的科目
public void setInfo(int age, String name, String sex, String course) {
super.age = age;
super.name = name;
super.sex = sex;
this.course = course;
}
@Override
public void fry() {
System.out.println("我会炒菜");
}
@Override
public void sing() {
System.out.println("我会唱歌");
}
@Override
public void showInfo() {
System.out.println("会唱歌的厨子的老师的信息是:");
System.out.println(super.name);
System.out.println(super.age);
System.out.println(super.sex);
System.out.println(this.course);
}
}
总结:
- 抽象类是对于一类事物的高度抽象,其中既有属性也有方法,当需要对一类事物抽象的时候,应该使用抽象类,好形成一个父类。
- 接口是对方法的抽象,也就是对一系列动作的抽象。当需要对一系列动作抽象时,就使用接口,需要使用这些动作的类去实现相应的接口即可。
工厂模式
在真正的开发工作中,都是合作开发,每个开发人员写部分代码,大家集合在一起就是一个项目。
例如:在开发宝马车的过程中
/**
* 宝马车的产品接口
*/
public interface BWM {
//产品的信息介绍
void showInfo();
}
/**
* 构建具体车的类
*/
class BWM3i implements BWM{
@Override
public void showInfo() {
System.out.println("这个是宝马3i系");
}
}
class BWM5 implements BWM{
@Override
public void showInfo() {
System.out.println("这个是宝马5系");
}
}
class BWM7 implements BWM{
@Override
public void showInfo() {
System.out.println("这个是宝马7系");
}
}
/**
* 汽车生产工厂接口
*/
public interface BWMFactory {
BWM productBWM();
}
/**
* 实现具体车型的生产工厂
*/
class BWM3Factory implements BWMFactory {
@Override
public BWM productBWM() {
System.out.println("生产宝马3系车");
System.out.println("改造3系车,定名为BWM3i型号");
return new BWM3i();
}
}
class BWM5Factory implements BWMFactory {
@Override
public BWM productBWM() {
System.out.println("生产宝马5系车");
return new BWM5();
}
}
class BWM7Factory implements BWMFactory {
@Override
public BWM productBWM() {
System.out.println("生产宝马7系车");
return new BWM7();
}
}
public class Test2 {
public static void main(String[] args) {
BWM bwm3 = new BWM3Factory().productBWM();
bwm3.showInfo();
BWM bwm5 = new BWM5Factory().productBWM();
bwm5.showInfo();
BWM bwm7 = new BWM7Factory().productBWM();
bwm7.showInfo();
}
}
输出:生产宝马3系车 改造3系车,定名为BWM3i型号 这个是宝马3i系 生产宝马5系车 这个是宝马5系 生产宝马7系车 这个是宝马7系
结论:通过工厂把new对象隔离,通过产品的接口可以接受不同实际产品的实现类,实例的类型的改变不影响其他合作开发人员的编程。
内部类
内部类可分为成员内部类(static成员内部类和非static成员内部类)、局部内部类、匿名内部类。
- 可以声明为final
- 可以定义多个
- 可以声明为private或protected
public class Test3 {
private int a;
public int b;
class A {
int i;
public void setTest3Fileds(){
Test3.this.a = 1;
Test3.this.b = 2;
}
public void set() {
this.i = 10;
}
}
//如果内部类是static的,就不能使用外部类非static的成员
static class B {
}
public void setInfo() {
new A().setTest3Fileds(); //外部类要用自己内部类的对象,得先new内部类的对象
new A().set();
}
public void showInfo() {
System.out.println(this.a);
System.out.println(this.b);
}
public static void main(String[] args) {
Test3 test3 = new Test3();
test3.setInfo();
test3.showInfo();
}
}
内部类的作用:解决java不能多重继承的问题
/**
* 现在类A想同时获得类B和类C的方法,并且重写
* 可以使用内部类来变相实现类的多重继承,可以同时继承多个类
*/
class A {
public void testB() {
new InnerB().testB();
}
public void testC() {
new InnerC().testC();
}
private class InnerB extends B {
@Override
public void testB() {
System.out.println("这是重写之后的testB方法");
}
}
private class InnerC extends C {
@Override
public void testC() {
System.out.println("这是重写之后的testC方法");
}
}
}
class B {
public void testB() {
}
}
class C {
public void testC() {
}
}
public class Test4 {
public static void main(String[] args) {
A a = new A();
a.testB();
a.testC();
}
}