抽象类可以实例化吗?
我考虑了这个问题一晚上,看了好几篇别人的博客,结果各不相同,每个人都有各自的理解,后来才知道:
抽象类不能直接用new实例化对象。 那就是不能实例化。 要获取抽象类的对象,必须首先在类中继承抽象类,然后实例化子类。 也可以使用匿名内部类在抽象类中创建匿名子类,继承抽象类,并使用特殊语法实例化子类中的对象。 (我稍后再详细说)
这里重要的是,要研究这个问题,必须了解抽象类,并以万不离其宗为前提。 从抽象类的根源开始,加深对抽象类的理解吧。
让我们先来看看这个例子:
package com.my.animal; //动物类
公共课堂教学{
字符串名称; //名称
字符串颜色; //颜色
公共动态(字符串名称,字符串颜色) {this.name=name; this.color=color;
公共语音运行() {
system.out.println(name )四条腿跑得很快! ' );
}
//犬类继承动物类
classdogextendsanimal { public dog (字符串名称,字符串颜色) }
super(name,color );
}
//鱼类继承动物类
classfishextendsanimal { public fish (字符串名称,字符串颜色) }
super(name,color );
}
} classtest { publicstaticvoidmain (字符串[ ] args ) }
Dog dog=new Dog ('哈巴狗','白');
dog.run (;
Fish fish=new Fish ('锦鲤','红');
fish.run (;
}
}
执行结果:
哈巴狗四条腿跑得很快!
锦鲤四条腿跑得快!
你注意到问题了吗? 鱼怎么能用脚跑? 是原始的鱼吗? 哈哈,开玩笑的。 我想我马上就想好了怎么解决这个问题。 在子类中重写父类的run方法不就行了吗? 没错,确实这样就可以解决了。 但是,我以为没有。 你是怎么发现这个问题的? 是编译运行后看到的吗? 当然,也有不编译就能执行的了不起的人。 你不拿油炸豆腐啊。 也就是说,存在无法发现这个问题的风险。 也许对别人无所谓,但对我们程序员来说,最好不要犯这样低级的错误。 程序员应该有更高的追求。 不能在这里绊倒。 怎样才能使那个风险为零呢? 不,不能着急吃热豆腐。 然后,看我慢慢分析。
当前存在的问题:
1 .动物run方法描述不正确
2 .没有强制子类重写父类的run方法
解决方案:(抽象类的应用场景)
我们在描述某种事物时,发现那种事物确实存在某种行为。 但是,其行为目前并不具体。 那么,你可以提取该行为的声明,但不能实现该行为。 此时,需要将该行为称为抽象行为,并使用抽象类
让我们先来看看下面的例子:
package com.my.animal; //动物系(抽象系) ) )。
公共基础课堂教学{
字符串名称; //名称
字符串颜色; //颜色//制作方法
公共动态(字符串名称,字符串颜色) {this.name=name; this.color=color;
}
//非抽象的方法
公共语音eat
system.out.println(name )吃点什么! ' );
(//抽象的方法
公共abstract void run (;
} classdogextendsanimal { public dog (字符串名称,字符串颜色) }
super(name,color );
}
@Overridepublic voidrun () {
system.out.println(name )四条腿跑得很快! ' );
}
} classfishextendsanimal { public fish (字符串名称,字符串颜色) }
super(name,color );
}
@Overridepublic voidrun () {
system.out.println(name )摇着尾巴游泳! ' );
}
} classtest {公共静态void
main(String[] args) {Dog dog= new Dog("哈巴狗","白色");
dog.run();
Fish fish= new Fish("锦鲤","红色");
fish.run();
}
}
运行结果:
哈巴狗四条腿跑得快!!
锦鲤摇摇尾巴游啊游!!
这个问题解决了,那还有一个问题就是:抽象类能实例化对象吗?
看这个例子就知道了:
public abstract classAnimal {
String name;
String color;publicAnimal(String name,String color){this.name =name;this.color =color;
}public abstract voidrun();
}classTest{public static voidmain(String[] args) {
Animal a= newAnimal();
a.run();
}
}
运行结果:
Error:(45, 20) java: com.my.animal.Animal是抽象的; 无法实例化
抽象类注意的细节:
1.如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象的函数。
2.如果一个类出现了抽象的函数,那么该类也必须使用abstract修饰。
3.如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。
4.抽象类可以存在抽象方法,也可以存在非抽象方法,还可以不存在抽象方法,但是这样没任何意义,Java是不写废话的。
5.抽象类是不能实例化对象的
6.抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。
疑问:为什么抽象类不能实例化对象?
因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象类的对象调用抽象方法是没有任何意义的。
疑问排解了,故事结束了?不,学海本无底,我们来点扩展,就是开头提到的如何用匿名内部类去实例化子类对象。
看下面的例子:
package Practice_Anything;public abstract classJava_Abstract2 {public voida(){
System.out.println("我是抽象类中的一个非抽象方法");
}public staticJava_Abstract2 newIntences(){return newJava_Abstract2(){
};
}
}classTest2{public static voidmain(String[] args) {
Java_Abstract2 java_abstract2=Java_Abstract2.newIntences();
java_abstract2.a();
}
}
运行结果:
我是抽象类中的一个非抽象方法
这个故事到这就结束了,但是学习还没有停止,比如接口也是一种抽象类型,是抽象方法的集合,由此,我们是不是该联想到学习接口了呢?哈哈,学海本无底,前行莫彷徨!
此篇为本人原创,花了大概半天时间,找了不知多少相关资料整合而成,如若对你有用,记得推荐,如若哪有不当,感谢指正!
本文已独家授权给脚本之家(jb51net)公众号独家发布