抽象类
1. 为什么使用抽象类?类用于描述现实生活中的一类事物,类中属性、方法,方法都有方法体。
某种情况下,父类只能知道子类应该具备一个怎样的方法,但是不能明确知道子类如何实现该方法。
例如:几何图形(多态练习)。所有几何图形都应该具备一个计算面积的方法,但是不同几何图形计算面积的方式不同
Java 为上述问题提供了相应的解决办法:
Java 允许父类只是提供一个方法的声明,不提供具体的实现
具体的实现交给子类来完成,该方法称为“抽象方法”
拥有一个或多个抽象方法的类,称为“抽象类”
2. 如何使用抽象类?
关键字:abstract
abstract 修饰的类称为“抽象类”
①格式:访问控制修饰符 abstract class 类名{}
②抽象类中可以有非抽象方法,抽象类中可以没有抽象方法
③拥有一个或多个抽象方法的类,必须是抽象类
④**抽象类不能创建实例
⑤抽象类中可以声明构造器。
目的:当子类继承父类后,继承父类中所有的属性和方法,因此子类需要知道父类如何为对象进行初始化
abstract 修饰的方法称为“抽象方法”
①格式:访问控制修饰符 abstract 返回值类型 方法名(参数列表);
②子类继承父类后,若重写了父类中“所有”的抽象方法,该类为具体类,可以创建实例
③子类继承父类后,若没有重写父类中“所有”的抽象方法,该类必须是抽象类,不能创建实例
3.注意
abstract 和 final 不能同时使用
abstract 和 static 不能同时使用
abstract 和 private 不能同时使用
接口
①接口与类是平级的。
关键字:interface
如:
public interface Flyer{}
②可以把接口理解为特殊的抽象类,因为接口中只能定义“全局静态常量”和“抽象方法”
//全局静态常量
int NUM = 10;//等同于public static final int NUM = 10;
//抽象方法
void fly();//等同于public abstract void fly();
③接口中不能使用变量、一般方法、构造器、代码块
④**接口不能创建实例
⑤接口就是用来被实现的
关键字:implements
如:
public class Bird implements Flyer{}
⑥实现接口的类称为“实现类”,实现类与“继承”的功能一样,实现类可以“继承”接口中所有内容
⑦若实现类没有实现接口中“所有”的抽象方法,该类必须是抽象类,不能创建实例
若实现类实现了接口中“所有”的抽象方法,该类为具体类,可以创建实例
⑧接口可以多实现 ------ 解决了 Java 中单继承的局限性
如:
public class Bird implements Flyer, Runner{}
⑨接口不能继承任何类,接口可以继承接口,并且可以多继承接口
⑩一个类可以继承另一个类,同时实现多个接口
如:
pulbic class Bird extends Animal implements Flyer, Runner{}
注意:先继承,后实现
Flyer f = new Bird();//多态
f.fly(); //虚拟方法调用
内部类
类的成员之一:内部类(属性、方法、构造器、代码块)1.成员内部类:一个类中声明另一个类,里面的类,称为“内部类”,外面的类,称为“外部类”
①是类的成员之一
②内部类可以使用四种访问控制修饰符(public protected default private)
③static final
//创建静态内部类的对象
Person.Mobile pm = new Person.Mobile();
pm.show();
//创建非静态内部类对象
Person p = new Person();
Person.Computer pc = p.new Computer();
Person.Computer pc2 = new Person().new Computer();
pc.setName("IBM");
④内部类与外部类具有相同的特性
class Person{
private String name;
private int age;
public Person(){}
public void setName(String name){
this.name = name;
}
//成员内部类
public class Computer{
private String name;
public void setName(String name){
System.out.println(age);
System.out.println("局部变量 name:" + name);
System.out.println("当前 Computer 对象的 name:" + this.name);
System.out.println("当前 Person 对象的 name:" + Person.this.name);
this.name = name;
}
}
//实现对类的隐藏
private class Heas{}
//静态内部类
static class Mobile{
public void show(){}
}
}
2.局部内部类:
//如下方式应用较少
public void show(){
int num = 10;//若局部内部类中使用了同级别的局部变量时,该局部变量必须使用 final 修饰
//局部内部类
class InnerClass{
}
InnerClass inner = new InnerClass();
}
//若某个类仅适用于当前方法时,可以声明如下:
public Comparator getComparator(){
//局部内部类
class MyComparator implements Comparator{
public int compare(Object o1, Object o2){}
}
return new MyComparator();
}
Comparator com = getComparator();
com.compare(1,2);
public Comparator getComparator(){
//匿名内部类
Comparator com = new Comparator(){
public int compare(Object o1, Object o2){}
};
return com;
}
public Comparator getComparator(){
return new Comparator(){
public int compare(Object o1, Object o2){}
};
}
枚举
枚举:jdk 1.5 后出的新特性。可以定义有限数量的可穷举数据集
简而言之,当确定一个类有几个对象时,就使用枚举
1. 自定义枚举类
①私有化构造器
②类的内部创建对象
/*
* 自定义枚举类
*/
public class Season2 {
private String seasonName;
private String seasonDesc;
// 2. 类的内部创建对象
public static final Season2 SPRING = new Season2("春天", "春眠不觉晓");
public static final Season2 SUMMER = new Season2("夏天", "处处蚊子咬");
public static final Season2 AUTUMN = new Season2("秋天", "秋天叶子黄");
public static final Season2 WINTER = new Season2("冬天", "冬天雪花飘");
// 1. 私化构造器
private Season2(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public void setSeasonName(String seasonName) {
this.seasonName = seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
public void setSeasonDesc(String seasonDesc) {
this.seasonDesc = seasonDesc;
}
@Override
public String toString() {
return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]";
}
}
2. enum 关键字创建枚举类
public enum Season2 {
SPRING,
SUMMER,
AUTUMN,
WINTER;
}
3. 枚举类实现接口
public enum Season implements MyInterface{
SPRING{
public void show(){
System.out.println("春天");
}
},
SUMMER{
public void show(){
System.out.println("夏天");
}
},
AUTUMN{
public void show(){
System.out.println("秋天");
}
},
WINTER{
public void show(){
System.out.println("冬天");
}
};
/*@Override
public void show() {
System.out.println("季节");
}*/
}