我的理解就是,抽象类就是把几个有部分相同方法和变量的类抽象出来写一个父类,然后子类里方法全部由父类重写而来。抽象类只是定义了这些通用的方法和变量,但是并没有定死方法的具体实现,变量也采用了泛型来"泛指"。
其实抽象类并不难理解,难的是“抽象”的能力。你怎么就知道哪些方法,哪些变量可以抽象出来呢?把所有具体类都写出来然后对比代码后重构?来来小伙子,把这99个具体类写一下。
这应该算是“架构”级别的思维能力了。留个引子,以后思考有所得了再记录。
当然一切都得从基础出发,让我们先学习抽象类的基本概念。
举个例子:
//抽象类
public abstract class Food {
public abstract void Cooking();
}
//具体实现子类I
public class Tomato extends Food{
@Override
public void Cooking() {
Log.d(TAG, "Cooking: 炒");
}
}
//具体实现子类II
public class Potato extends Food{
@Override
public void Cooking() {
Log.d(TAG, "Cooking: 炖");
}
抽象类里面有个抽象方法,两个子类分别实现了这个方法。
这么看起来似乎抽象类根本就是多余的?并不,你因此得知Food这玩意你需要Cooking了之后才能吃,贝爷的事迹看看就好。
扩展一下这个例子
public abstract class Food {
public abstract String Cooking();
public String DishName(){
return Cooking()+"FoodName";
}
}
//具体实现子类I
public class Tomato extends Food{
@Override
public void Cooking() {
return "炒";
}
}
//具体实现子类II
public class Potato extends Food{
@Override
public void Cooking() {
return "炖";
}
public class ServieDish {
Tomato tomato = new Tomato();
Potato potato = new Potato();
String DishName1 = tomato.DishName(); //炒+"FoodName"
String DishName2 = potato.DishName();//炖+"FoodName"
}
可以看到,父类里面定义了 DishName(),返回了这道菜的全名。满汉全席一百零八道菜,我们只写了一个DishName()方法呢,棒棒哒。子类直接调用父类的方法哟。
“FoodName“是个什么鬼,再扩展一下这个例子
修改抽象类,添加了一个setFoodName的方法。
public abstract class Food{
private String FoodName;
public void setFoodName(String foodName) {
FoodName = foodName;
}
public abstract String Cooking();
public String DishName(){
return Cooking()+FoodName;
}
}
在实例化子类的时候,调用父类的setFoodName的方法
Potato potato = new Potato();
potato.setFoodName("土豆");
Tomato tomato = new Tomato();
tomato.setFoodName("番茄");
使用父类的方法,其实体现的是“继承”的思想。
如果用泛型来传入“土豆”
public abstract class Food<T>{
private T foodName;
Food(T foodName){
this.foodName = foodName;
}
public abstract String Cooking();
public String DishName(){
return Cooking()+foodName;
}
}
定义子类的时候传入一个String类型的参数作为泛型的具体实现
public class Potato extends Food<String>{
public Potato(String foodName) {
super(foodName);//通过super调用父类构造器的初始化过程
}
@Override
public String Cooking() {
return "炖";
}
}
使用这个子类
Potato potato = new Potato("土豆");
Log.d("Food", potato.DishName());//打印结果为:炖土豆
可是我想吃土豆炖牛肉
public abstract class Food<T>{
private List<T> foodName;
Food(List<T> foodName){
this.foodName = foodName;
}
public abstract String Cooking();
public String DishName(){
return foodName.get(0)+Cooking()+foodName.get(1);
}
}
public class Potato extends Food<String>{
public Potato(List<String> info) {
super(info);//通过super调用父类构造器的初始化过程
}
@Override
public String Cooking() {
return "炖";
}
}
List<String> foodName = new ArrayList<>();
foodName.add("土豆");
foodName.add("牛肉");
Potato potato = new Potato(foodName);
Log.d("Food", potato.DishName());