简体   繁体   English

继承如何在java中使用抽象类

[英]how does inheritance work with abstract classes in java

I am writing small pieces of code to make sure I understand Java basics and I have the following. 我正在编写一小段代码以确保我理解Java基础知识,并且我有以下内容。

package teams1;

public abstract class Team1{
    private String sport = new String();

    public abstract String getSport();

    public abstract void setSport();
}

import teams1.*;
abstract class FootballTeam1 extends Team1{

    public String getSport(){
        return "Football";
    }

    public void setSport(){
        this.sport="Football";
    }
}

It doesn't compile because sport is private in the super class, but I thought FootballTeam1 would inherit it's own copy of sport because it is extending Team1. 它没有编译,因为运动在超级类中是私有的,但我认为FootballTeam1将继承它自己的运动副本,因为它正在扩展Team1。 Any help would be appreciated. 任何帮助,将不胜感激。 Thanks! 谢谢!

You have mostly answered your own question. 你大多回答了自己的问题。 FootballTeam1 does not have access to the private fields of its parent. FootballTeam1无权访问其父级的私有字段。 That is what the ' protected ' scope is used for. 这就是“ 受保护 ”范围的用途。

However, the child FootballTeam1 does have its own copy of the field. 但是,子FootballTeam1确实有自己的字段副本。 It has a copy of all fields that the parent class has, which I can see would cause confusion. 它有父类所有字段的副本,我可以看到它会引起混淆。

The reason for this distinction is modularity. 这种区别的原因是模块化。 A subclass of a parent class only has access to the parts of the parent class that one has explicitly stated that it may have access to. 父类的子类只能访问父类的部分,这些部分已明确声明它可以访问。 This allows developers to consider what parts of a class are to be exposed, under the Object Orientated goal known as the ' Open/Closed Principle '; 这允许开发人员在面向对象的目标(称为“ 开放/封闭原则 ”)下考虑要暴露的类的哪些部分; that is, classes should be open for extension, but closed for modification. 也就是说,类应该是开放的扩展,但是关闭以进行修改。

The quickest 'fix' to the class is change the scope of the field, for example 例如,对类的最快“修复”是改变字段的范围

private String sport = new String();

becomes

protected String sport = new String();

or 要么

public String sport = new String();

If you do not want to give the child class direct access to the field, but do want to allow it to change the field then a protected setter method could be used. 如果您不想让子类直接访问该字段,但确实希望允许它更改字段,则可以使用受保护的setter方法。 For example, you could add the following to Team1 . 例如,您可以将以下内容添加到Team1

protected void setSport( String newValue ) {
    this.sport = newValue;
}

Since the class variable sport is private, it is private to the class it was declared in. Extending classes cannot access this variable in the manner you are trying. 由于类变量sport是私有的,因此对于声明它的类是私有的。扩展类不能以您尝试的方式访问此变量。

Try making the variable protected (which allows extending classes to have visibility on the variable) if you want to continue accessing the sport variable in this manner, otherwise have getters and setters in the abstract class and the extending/implementing classes to call them instead. 如果要以这种方式继续访问sport变量,请尝试使变量protected (允许扩展类对变量具有可见性),否则在抽象类和扩展/实现类中使用getter和setter来调用它们。

Private Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. 声明为private的Private方法,变量和构造函数只能在声明的类本身中访问。

Protected Variables, methods and constructors which are declared protected in a superclass can be accessed only by the subclasses in other package or any class within the package of the protected members' class. 在超类中声明受Protected变量,方法和构造函数只能由其他包中的子类或受保护成员类的包中的任何类访问。

Modified code : 修改后的代码

package com.org.abstractc;
public abstract class Team1{
    // you have to change this private to protected then it will be inherited 
    // in child class.
    protected String sport = new String();   

    public abstract String getSport();

    public abstract void setSport();
}

Just change private to protected . 只需将private更改为protected private means that your subclasses don't have access to variables or methods, whereas protected allows this access. private表示您的子类无权访问变量或方法,而protected允许此访问。

Private fields are accessible only in the same class. 私有字段只能在同一个类中访问。 Also, inheritance is mainly used for defining the same name methods in derived classes with seperate functional logic. 此外,继承主要用于在具有单独功能逻辑的派生类中定义相同的名称方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM