好家伙,这个作者竟然妄图一天就把面向对象的两个特征说了。他可真是自不量力啊,作者心中OS:学习真累,赶快写完去打游戏真香。
正文分割线
一、抽象
1、抽象的定义:抽象,字面意思。很抽象,很多人都不懂的东西就叫抽象。那么放在Java中是什么样的体现呢?百度百科的答案是:抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料通过去粗取精、去伪存真、由此及彼、由表及里的加工制作,形成概念、判断、推理等思维形式,以反映事物的本质和规律的方法。
2、Java中抽象的体现:
抽象类:抽象方法必须写在抽象类中,抽象类中可以有除了抽象方法以外的方法。抽象方法意味着在本类中我自己这个类不实现这个方法,这个方法需要通过子类帮我实现。就像你的老板,他只是给你提供了一个解决问题的思路,但是具体流程怎么落地,还是得看你自己怎么做。
接口:接口的话后面会说,现在说了就不能多水一个文章了。
3、抽象类的关键字:
abstract:抽象类定义时,abstract写在class前面。抽象方法定义时,abstract写在返回值定义之前。一个方法定义为抽象类之后,他就可以不用写{},而是应该直接分号结尾来结束这个语句。
二、多态
1、多态的定义:同样的方法,不同的实现就是Java中的多态。
2、静态多态
重载:相同的类中,允许写多个方法名一样的方法。
3、动态多态
重写:子类重新实现父类的方法,前提是要和父类中的方法一样。重写父类的方法时,不能比父类的方法范围大,假如父类使用protect修饰,那么子类不能用public。而且返回值也得一样。前两个点的原理是子类不能比父类抛出更多的异常,而修改这些东西有可能会造成比父类造成更多的异常。
动态绑定:根据传入方法的对象不同,来执行不同的方法。在说具体一点:当子类重写父类的方法时,这时候就存在了两个相同名字,相同类型的方法。那么在程序加载中的时候,程序应该调用哪个呢?这个时候就会根据你传入的对象是子类还是父类进行选择。假如传入是子类就会执行子类的方法。
类型转换:符合继承关系的两个类,支持子类自动向上转型为父类,但是父类向下转型的话还是要强制转换,使用()。
代码举例
package UnAble;
/*** 用于演示抽象和多态的类* @author 84980**/
public class Test {
public static void main(String[] args) {
//通过实现类的实例化来赋值给抽象类,因为抽象类是不能实例化的fatherAb fab=new child();
//调用抽象类自身实现的方法fab.ill();
//调用抽象子类的实现方法fab.hello();
//实例化父类Father f=new Father();
//调用父类中的方法human(f);
//实例化子类ChildBen c=new ChildBen();
//正常调用子类中的方法human(c);
//创建一个父类的对象,但是把子类赋值给它,子类会自动转换为父类Father cff=new ChildBen();
//虽然cff定义是父类对象,但实际上他是由子类传入,所以调用下面的测试方法还是会输出子类的方法,这就是动态绑定human(cff);
//父类对象强制转换为子类对象,为了避免强制转型带来的风险,我们需要使用instanceof来判断这个对象是否是子类if (cff instanceof ChildBen) {
ChildBen cf = (ChildBen) cff;
human(cf);
}
}
/*** 测试动态多态的方法*/
public static void human(Father f) {
f.walk();
}
}
//因为定义了抽象方法,所以该类就必须设置为抽象类abstract class fatherAb{
//定义一个抽象方法public abstract void hello();
//抽象类中的非抽象方法public void ill() {
System.out.println("我是抽象类中的非抽象方法");
}
}
class child extends fatherAb{
@Override
public void hello() {
// TODO 自动生成的方法存根System.out.println("我是实现父类抽象方法的子类");
}
}
class Father{
public void walk() {
System.out.println("我是爸爸,我会走路");
}
}
class ChildBen extends Father{
public void walk() {
System.out.println("我是儿子,我也会走路");
}
}