通过避免继承来避免破坏类的行为
站在用户的角度思考问题,与客户深入沟通,找到北海街道网站设计与北海街道网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站建设、网站制作、企业官网、英文网站、手机端网站、网站推广、国际域名空间、网站空间、企业邮箱。业务覆盖北海街道地区。Java的优势之一是继承的概念,其中一个类可以从另一个类派生,但有时最好防止另一个类的继承。 为了防止继承,在创建类时使用关键字“ final”。
例如,如果一个类可能被其他程序员使用,则如果创建的任何子类可能引起问题,则你可能希望防止继承。 一个典型的例子是String类。 如果我们想创建一个String子类:
public class MyString extends String{
}
我们将面临以下错误:
cannot inherit from final java.lang.String
String类的设计者意识到它不是继承的候选者,因此阻止了对其进行扩展。
为什么要防止继承?
防止继承的主要原因是确保类的行为方式不会被子类破坏。
假设我们有一个Account类和一个扩展它的子类OverdraftAccount。 类帐户具有方法getBalance():
public double getBalance()
{
return this.balance;
}
至此,在我们的讨论中,子类OverdraftAccount尚未覆盖此方法。
(注意:有关使用此Account和OverdraftAccount类的另一讨论,请参见如何将子类视为超类)。
让我们为每个Account和OverdraftAccount类创建一个实例:
Account bobsAccount = new Account(10);
bobsAccount.depositMoney(50);
OverdraftAccount jimsAccount = new OverdraftAccount(15.05,500,0.05);
jimsAccount.depositMoney(50);
//create an array of Account objects
//we can include jimsAccount because we
//only want to treat it as an Account object
Account[] accounts = {bobsAccount, jimsAccount};
//for each account in the array, display the balance
for (Account a:accounts)
{
System.out.printf("The balance is %.2f%n", a.getBalance());
}
The output is:
The balance is 60.00
The balance is 65.05
一切似乎都按预期工作,在这里。 但是,如果OverdraftAccount覆盖方法getBalance()怎么办? 没有什么可以阻止它执行以下操作:
public class OverdraftAccount extends Account {
private double overdraftLimit;
private double overdraftFee;
//the rest of the class definition is not included
public double getBalance()
{
return 25.00;
}
}
如果再次执行上述示例代码,则输出将有所不同,因为jimsAccount调用了OverdraftAccount类中的getBalance()行为:
The output is:
The balance is 60.00
The balance is 25.00
不幸的是,子类OverdraftAccount将永远不会提供正确的余额,因为我们已经通过继承破坏了Account类的行为。
如果您设计一个供其他程序员使用的类,请始终考虑任何潜在子类的含义。 这就是不能扩展String类的原因。 程序员必须知道,当他们创建一个String对象时,它总是会表现得像String一样,这一点非常重要。
如何防止继承
要阻止类扩展,类声明必须明确声明它不能被继承。 这可以通过使用“ final”关键字来实现:
public final class Account {
}
这意味着Account类不能是超类,而OverdraftAccount类不能再作为其子类。
有时,您可能希望仅限制超类的某些行为,以避免子类损坏。 例如,OverdraftAccount仍然可以是Account的子类,但是应避免覆盖getBalance()方法。
在这种情况下,使用方法声明中的“ final”关键字:
public class Account {
private double balance;
//the rest of the class definition is not included
public final double getBalance()
{
return this.balance;
}
}
注意在类定义中如何不使用final关键字。 可以创建Account的子类,但是它们不能再覆盖getBalance()方法。 任何调用该方法的代码都可以确信它会按原始程序员的意图工作。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。