Java访问修饰符

时间:2020-01-09 10:35:40  来源:igfitidea点击:

Java访问修饰符指定哪些类可以访问给定的类及其字段,构造函数和方法。可以为类,其构造函数,字段和方法分别指定访问修饰符。 Java访问修饰符有时在日常用语中也称为Java访问修饰符,但正确的名称是Java访问修饰符。类,字段,构造函数和方法可以具有四个不同的Java访问修饰符之一:

  • private
  • default (package)
  • protected
  • public

这些Java访问修饰符将在本Java访问修饰符教程的以下各节中介绍。下表总结了每个Java访问修饰符可以应用到的Java构造:

privatedefaultprotectedpublic
私有默认受保护公共
嵌套类别
构造函数
方法
字段

将访问修饰符分配给类,构造函数,字段或者方法有时也称为"标记"该访问修饰符指定的类,构造函数,字段或者方法。例如,将Java访问修饰符" public"分配给方法将被称为将方法标记为" public"。

专用访问修饰符

如果将方法或者变量标记为"私有"(已为其分配了"私有"访问修饰符),则只有同一类内的代码才能访问该变量或者调用该方法。子类中的代码无法访问变量或者方法,也不能从任何外部类中进行代码。

类不能用" private"访问修饰符标记。用" private"访问修饰符标记一个类将意味着没有其他类可以访问它,这意味着我们根本无法真正使用该类。因此,类不能使用" private"访问修饰符。

这是将" private"访问修饰符分配给字段的示例:

public class Clock {
    private long time = 0;
}

成员变量"时间"已被标记为"私有"。这意味着,不能从"时钟"类外部的代码访问"时钟"类内部的成员变量"时间"。

通过访问器方法访问私有字段

通常将字段声明为"私有",以控制外界对其的访问。在某些情况下,这些字段是真正私有的,这意味着它们仅在类中内部使用。在其他情况下,可以通过访问器方法(例如getter和setter)访问这些字段。这是一个访问器方法示例:

public class Clock {
    private long time = 0;

    public long getTime() {
        return this.time;
    }

    public void setTime(long theTime) {
        this.time = theTime;
    }
}

在上面的示例中,两个方法getTime()和setTime()可以访问time成员变量。这两个方法都声明为" public",这意味着可以在应用程序中任何位置的代码中调用它们。本文稍后将介绍" public" Java访问修饰符。

private构造函数

如果为类中的构造函数分配了"私有" Java访问修饰符,则意味着无法从类外部的任何地方调用该构造函数。仍然可以从其他构造函数或者同一类的static方法中调用一个private构造函数。这是一个Java类示例,说明了这一点:

public class Clock {

    private long time = 0;

    private Clock(long time) {
        this.time = time;
    }

    public Clock(long time, long timeOffset) {
        this(time);
        this.time += timeOffset;
    }

    public static Clock newClock() {
        return new Clock(System.currentTimeMillis());
    }

}

这个版本的Clock类包含一个private构造函数和一个public构造函数。从公共构造函数中调用" private"构造函数(语句" this();")。 private构造函数也可以从static方法newClock()中调用。

上面的示例仅向我们显示可以从公共构造函数和同一类中的static方法调用"私有"构造函数。请勿以任何方式将上述示例视为聪明设计的示例。

默认(程序包)访问修饰符

通过根本不编写任何访问修饰符来声明默认的Java访问修饰符。默认访问修饰符意味着,类本身内部的代码以及与此类位于同一包中的类内部代码,都可以访问分配了默认访问修饰符的类,字段,构造函数或者方法。因此," default"访问修饰符有时也称为" package"访问修饰符。如果我们不知道Java包是什么,我已经在Java包教程中对此进行了解释。

子类不能访问超类中的方法和成员变量(字段),如果它们用默认的访问修饰符标记,除非子类与超类位于同一包中。

这是默认的/包访问修饰符示例:

public class Clock {
    long time = 0;
}

public class ClockReader {
    Clock clock = new Clock();

    public long readClock{
        return clock.time;
    }
}

"时钟"类中的"时间"字段没有访问修饰符,这意味着为它隐式分配了默认/包访问修饰符。因此,只要ClockReaderClock位于同一Java包中,ClockReader类就可以读取Clock对象的time成员变量。

受保护的访问修饰符

" protected"访问修饰符提供与" default"访问修饰符相同的访问权限,此外,子类可以访问" protected"方法和超类的成员变量(字段)。即使子类与超类不在同一个包中,也是如此。

这是一个"受保护的"访问修饰符示例:

public class Clock {
    protected long time = 0;    // time in milliseconds
}

public class SmartClock() extends Clock{

    public long getTimeInSeconds() {
        return this.time / 1000;
    }
}

在上面的示例中,子类SmartClock具有名为getTimeInSeconds()的方法,该方法访问超类Clock的time变量。即使ClockSmartClock不在同一个包中,这也是可能的,因为time字段标记有protectedJava访问修饰符。

公共访问修饰符

Java访问修饰符" public"意味着所有代码都可以访问类,字段,构造函数或者方法,而不管访问代码位于何处。访问代码可以在不同的类和不同的包中。

这是一个public访问修饰符示例:

public class Clock {
    public long time = 0;
}

public class ClockReader {
    Clock clock = new Clock();

    public long readClock{
        return clock.time;
    }
}

"时钟"类中的"时间"字段标记有"公共" Java访问修饰符。因此,无论ClockReader位于哪个包中,ClockReader类都可以访问Clock中的time字段。

类访问修饰符

重要的是要记住,分配给Java类的Java访问修饰符优先于分配给该类的字段,构造函数和方法的所有访问修饰符。如果该类标记有"默认"访问修饰符,则同一Java包之外的其他任何类都不能访问该类,包括其构造函数,字段和方法。将这些字段声明为" public",甚至是" public static"都无济于事。

Java访问修饰符" private"和" protected"不能分配给一个类。仅适用于类内的构造函数,方法和字段。类只能分配给默认类(包)和" public"访问修饰符。

接口访问修饰符

Java接口用于指定在实现接口的类中公共可用的字段和方法。因此,我们不能在接口中使用"私有"和"受保护"访问修饰符。如果省略访问修饰符,则接口中的字段和方法将隐式声明为" public",因此也不能使用默认访问修饰符(无访问修饰符)。

访问修饰符和继承

当创建某个类的子类时,子类中的方法所分配的访问修饰符不能比超类中的方法少。例如,如果超类中的方法是" public",那么子类中的方法也必须是" public",以防子类覆盖该方法。如果超类中的方法是"保护的",那么它在子类中必须是"保护的"或者"公共的"。

虽然不允许降低覆盖方法的可访问性,但允许扩展覆盖方法的可访问性。例如,如果在超类中为方法分配了默认的访问修饰符,则允许在子类中为" public"访问修饰符分配重写的方法。