我们都知道Java有三大特性为:封装、继承、多态。
封装:隐藏代码的实现细节(比如属性、方法),对外提供公共的接口,用户只要根据接口调用方法即可。
继承:字面意思在保留原来属性和方法的同时,我可以添加更多的属性和方法或者也可以说把相同的属性和方法抽取出来单独放在一个类里面,保留自己独有的属性和方法。
那什么是多态呢?
我们假设有一个食谱,第一周的主食为大米:
public class DaMi {
public void eat(){
System.out.println("这周主食是大米");
}
}
第二周的主食为面条:
public class Miantiao {
public void eat(){
System.out.println("这周主食是面条");
}
}
如果们要在main方法里面输出第一周主食,我们必须创建一个DaMi对象:
public static void main(String[] args) {
DaMi daMi = new DaMi();
daMi.eat();
}
同样我们要是输出第二周主食,我们必须创建一个MianTiao对象:
public static void main(String[] args) {
MianTiao mianTiao = new MianTiao();
mianTiao.eat();
}
这样如果我们有很多主食就要创建很多的对象,这是后期的管理是十分麻烦的,那么有没有什么解决方案呢?
我们观察到无论是大米还是面条都有相同的方法eat(),那能不能抽取出来单独放在一个类里面呢?答案是肯定的,既然他们都有eat()方法,但是输出内容不同,那么我们可以提供一个接口,里面规定有吃这个行为即eat()方法,然后让他们分别去实现这个方法就行了:
//接口
public interface Food {
public void eat();
}
//大米实现类
public class DaMi implements Food {
@Override
public void eat(){
System.out.println("这周主食是大米");
}
}
//面条实现类
public class MianTiao implements Food {
@Override
public void eat() {
System.out.println("这周主食是面条");
}
}
在main方法里面再次输出主食,我们只需根据需求看是要大米还是面条,只需创建一个对象即可:
static Food food = new DaMi();
// static Food food = new MianTiao();
public static void main(String[] args) {
food.eat();
}
这就是多态的思想,即同一个行为具有不同表现形式或形态的能力,我们只需要根据需求为food指向不同的子类对象,而不需要修改main里面的代码。这极大增加了代码的可复用性,提高了后期代码的维护性。
上面的例子简单说明了一下多态的应用和优点,观察上面的例子我们也发现,我们必须提前给food赋值即在代码里面已把food写死了,外部无法改变,控制权在我们自己手里。客户无法根据自己需求灵活的输出大米或者面条,那有没有什么办法不提前写好food的指向,让用户根据自己的需求填写对应的指向呢?
SpringIOC控制反转思想
IOC思想帮助我们解决了这个问题。IOC即控制反转,字面理解就是控制权的转变,即创建对象的控制权由原先的我们自己现在交给spring这个容器来管理。怎么理解呢?还是根据上面的例子,要想不写死food的指向,我们只需添加一个set方法即可:
Food food;
public void setFood(Food food) {
this.food = food;
food.eat();
}
public static void main(String[] args) {
xxx.setFood(new DaMi());
}
这样我们根据我们的需求在setFood()方法里传入不同的参数,就能实现输出不同的主食。观察添加set方法前后,我们不难发现,添加前创建对象的控制权在我们手里,我们让创建什么对象就创建什么对象,添加之后控制权交给了set方法,我们只提供参数,set方法根据参数为我们创建对应的对象。这就是控制反转思想的应用。
PS:以上就是我对多态和IOC的理解和总结,如果有什么不对的地方,欢迎您的指正,如果帮到了你,麻烦点个赞,十分感谢!