抽象类和抽象方法
下面让我们来理解一下抽象类和抽象方法吧:
有以下语句:
Pet pet=new Pet(“贝贝”);
pet.print();
这样的代码是没有意义的,只是一个抽象的概念,我们需要进行限制将Pet限制为不能实例化的。这就需要运用到Java中的抽象类来实现,用abstract来修饰Pet类,抽象类就不能通过new实例化。
代码如下:
public abstract class Pet {
private String name="无名氏";//昵称
private int health=100;//健康值
private int love=0;//亲密度
/**
* 有参构造方法
*/
public Pet(String name){
this.name=name;
}
public String getName() {
return name;
}
public int getHealth() {
return health;
}
public int getLove() {
return love;
}
/**
* 输出宠物信息
*/
public void print(){
System.out.println("宠物的自白:\n我的名字叫"+this.name+",健康值是"+this.health+",和主人的亲密度是"+this.love+"。");
}
}
/*
* 测试抽象类是否能实例化
*/
public class TestPet {
public static void main(String[] args) {
//1.创建宠物对象pet并输出信息
Pet pet=new Pet("贝贝");
pet.print();
运行结果如下:
显示抽象类不能实例化!!
问题:Pet类提供了print()方法,如果子类重写该方法,则将正确输出子类的信息。可是如果子类没有重写该方法,则子类将继承Pet类的该方法,从而无法输出子类信息。我们能否强迫子类必须重写该方法,否则报错呢?
修改以上代码,来验证一下吧:
/**
* 宠物类,狗狗和企鹅的父类
*
*/
public abstract class Pet {
private String name="无名氏";//昵称
private int health=100;//健康值
private int love=0;//亲密度
/**
* 有参构造方法
*/
public Pet(String name){
this.name=name;
}
public String getName() {
return name;
}
public int getHealth() {
return health;
}
public int getLove() {
return love;
}
/**
* 抽象方法,输出宠物信息
*/
public abstract void print();
}
将Dog类中去掉print()方法的定义,即不重写print()方法,代码如下:
/**
* 狗狗类,宠物的子类
*/
public class Dog extends Pet{
private String strain;//品种
/**
* 有参构造方法
*/
public Dog(String name,String strain) {
super(name);//此处不能用this.name=name
this.strain = strain;
}
public String getStrain() {
return strain;
}
提示如下:
子类不重写抽象方法会报错!!
这个错误的解决方法就是在Dog类中重写print()方法。
抽象类和抽象方法的特点如下。
1.抽象类和抽象方法都通过abstract关键字来修饰。
2.抽象类不能实例化。抽象类中可以没有,有一个或多个抽象方法,甚至全部方法都可以是抽象方法。
3.抽象方法只有方法声明,没有方法实现。有抽象方法的类必须声明为抽象类,子类必须重写所有的抽象方法才能实例化,否则子类还是一个抽象类。
问题
抽象类中可以有构造方法嘛?
解答:抽象类中可以有构造方法,其构造方法可以被本类的其他构造方法调用,若此构造方法不是由private修饰,也可以被本类的子类中的构造方法调用。
final修饰符
final的应用
1.用final修饰的类,不能再被继承
如以下代码所示:
final class Penguin{}
class SubPenguin extends Penguin{//此行出现错误 提示信息为:The type SubPenguin cannot subclass the final class,即Penguin类不能被继承。
}
2.用final修饰的方法不能被子类重写
代码如下:
class Penguin{
public final void print(){}
}
class SubPenguin extends Penguin{
public void print(){}//此行出现错误 提示信息为:cannot override the final method form Penguin,即pring()方法不能被子类重写。
}
3.用final修饰的变量(包括成员变量和局部变量)将变成常量,只能赋值一次
代码如下:
public class Penguin{
final String home="南极";//居住地
public void setHome(String name){
this.home=home;//错误,home不可以再次赋值 提示信息为:The final field Penguin.home cannot be assigned,即home不可以再次赋值。
}
}
final和abstract的区别
abstract可以用来修饰类和方法,不能用来修饰属性和构造方法。
final可以用来修饰类,方法和属性,不能修饰构造方法
知识点
Java提供的很多类都是final类,如String类,Math类,它们不能再有子类。Object类中一些方法,如getClass(),notify(),wait()都是final方法,只能被子类继承而不能被重写,但是hashCode(),toString(),equals(Object obj)不是final方法,可以被重写。
使用final修饰引用型变量时,变量的值是固定不变的。而变量所指向的对象的属性值是可变的。
abstract不能和private,static同时修饰一个方法,不能和final同时修饰一个方法或类。