Java 使用super关键字从不同包调用基类的受保护构造函数
如何在一个包中调用基类的构造函数,该包保护访问修饰符不受另一个包中派生的访问修饰符的影响? 这样地: 包含派生类的包:Java 使用super关键字从不同包调用基类的受保护构造函数,java,inheritance,constructor,packages,super,Java,Inheritance,Constructor,Packages,Super,如何在一个包中调用基类的构造函数,该包保护访问修饰符不受另一个包中派生的访问修饰符的影响? 这样地: 包含派生类的包: package MainPack; import mypack.Checker; import java.util.Scanner; public class Start { public static void main(String[] args) { BeginCheck bc=new BeginCheck(); } } class
package MainPack;
import mypack.Checker;
import java.util.Scanner;
public class Start
{
public static void main(String[] args)
{
BeginCheck bc=new BeginCheck();
}
}
class BeginCheck extends Checker
{
BeginCheck()
{
System.out.print("Enter a String to Check: ");
super(new Scanner(System.in).nextLine()); //I want to call it like this
}
}
包含基类的包:
package mypack;
public class Checker
{
String s;
protected Checker()
{
}
protected Checker(String s)
{
s=this.s;
}
}
对超级构造函数的调用必须是每个构造函数的第一行。除非调用默认构造函数,否则可以省略该调用,编译器将对其进行推断
BeginCheck() {
super( new Scanner( System.in ).nextLine() );
}
不过,您确实不应该在构造函数中执行用户IO。它应该只用于将对象初始化为可用状态
对超级构造函数的调用必须是每个构造函数的第一行。除非调用默认构造函数,否则可以省略该调用,编译器将对其进行推断
BeginCheck() {
super( new Scanner( System.in ).nextLine() );
}
不过,您确实不应该在构造函数中执行用户IO。它应该只用于将对象初始化为可用状态
对超级构造函数的调用必须是每个构造函数的第一行。除非调用默认构造函数,否则可以省略该调用,编译器将对其进行推断
BeginCheck() {
super( new Scanner( System.in ).nextLine() );
}
不过,您确实不应该在构造函数中执行用户IO。它应该只用于将对象初始化为可用状态
对超级构造函数的调用必须是每个构造函数的第一行。除非调用默认构造函数,否则可以省略该调用,编译器将对其进行推断
BeginCheck() {
super( new Scanner( System.in ).nextLine() );
}
不过,您确实不应该在构造函数中执行用户IO。它应该只用于将对象初始化为可用状态。首先-不应该使用构造函数进行I/O。这是一种糟糕的形式 下面是一个例子,说明了为什么JLS需要一个
super()
调用作为子类构造函数中的第一条语句
class Gradient {
public final Color start;
public final Color end;
protected void blendTo(Color c1, Color c2, double BlendStart,
double blendEnd) {
// method to draw gradient blend
}
public Gradient(Color start, Color end) {
if (start == null || end == null) {
throw new IllegalArgumentException("No parameters can be null.");
}
this.start = start;
this.end = end;
blendTo(this.start, this.end, 0.0, 1.0);
}
}
class ThreeGradient extends Gradient {
public final Color middle;
// This is invalid Java code
public ThreeGradient(Color start, Color end, Color middle) {
this.middle = middle;
blendTo(this.start, this.middle, 0.0, 0.5); // If this were valid, it
// would attempt to use
blendTo(this.middle, this.end, 0.5, 1.0); // this.start and this.end
// before initialization.
super(start, end);
}
}
您可以看到,
ThreeGradient
依赖于其父级Gradient
中的数据,这是它应该能够做到的。如果其父级渐变未初始化,则它将无法正常工作。这是一个假设性的讨论,因为Java中不允许这样做 首先-不应该使用构造函数进行I/O。这是一种糟糕的形式
下面是一个例子,说明了为什么JLS需要一个super()
调用作为子类构造函数中的第一条语句
class Gradient {
public final Color start;
public final Color end;
protected void blendTo(Color c1, Color c2, double BlendStart,
double blendEnd) {
// method to draw gradient blend
}
public Gradient(Color start, Color end) {
if (start == null || end == null) {
throw new IllegalArgumentException("No parameters can be null.");
}
this.start = start;
this.end = end;
blendTo(this.start, this.end, 0.0, 1.0);
}
}
class ThreeGradient extends Gradient {
public final Color middle;
// This is invalid Java code
public ThreeGradient(Color start, Color end, Color middle) {
this.middle = middle;
blendTo(this.start, this.middle, 0.0, 0.5); // If this were valid, it
// would attempt to use
blendTo(this.middle, this.end, 0.5, 1.0); // this.start and this.end
// before initialization.
super(start, end);
}
}
您可以看到,ThreeGradient
依赖于其父级Gradient
中的数据,这是它应该能够做到的。如果其父级渐变未初始化,则它将无法正常工作。这是一个假设性的讨论,因为Java中不允许这样做 首先-不应该使用构造函数进行I/O。这是一种糟糕的形式
下面是一个例子,说明了为什么JLS需要一个super()
调用作为子类构造函数中的第一条语句
class Gradient {
public final Color start;
public final Color end;
protected void blendTo(Color c1, Color c2, double BlendStart,
double blendEnd) {
// method to draw gradient blend
}
public Gradient(Color start, Color end) {
if (start == null || end == null) {
throw new IllegalArgumentException("No parameters can be null.");
}
this.start = start;
this.end = end;
blendTo(this.start, this.end, 0.0, 1.0);
}
}
class ThreeGradient extends Gradient {
public final Color middle;
// This is invalid Java code
public ThreeGradient(Color start, Color end, Color middle) {
this.middle = middle;
blendTo(this.start, this.middle, 0.0, 0.5); // If this were valid, it
// would attempt to use
blendTo(this.middle, this.end, 0.5, 1.0); // this.start and this.end
// before initialization.
super(start, end);
}
}
您可以看到,ThreeGradient
依赖于其父级Gradient
中的数据,这是它应该能够做到的。如果其父级渐变未初始化,则它将无法正常工作。这是一个假设性的讨论,因为Java中不允许这样做 首先-不应该使用构造函数进行I/O。这是一种糟糕的形式
下面是一个例子,说明了为什么JLS需要一个super()
调用作为子类构造函数中的第一条语句
class Gradient {
public final Color start;
public final Color end;
protected void blendTo(Color c1, Color c2, double BlendStart,
double blendEnd) {
// method to draw gradient blend
}
public Gradient(Color start, Color end) {
if (start == null || end == null) {
throw new IllegalArgumentException("No parameters can be null.");
}
this.start = start;
this.end = end;
blendTo(this.start, this.end, 0.0, 1.0);
}
}
class ThreeGradient extends Gradient {
public final Color middle;
// This is invalid Java code
public ThreeGradient(Color start, Color end, Color middle) {
this.middle = middle;
blendTo(this.start, this.middle, 0.0, 0.5); // If this were valid, it
// would attempt to use
blendTo(this.middle, this.end, 0.5, 1.0); // this.start and this.end
// before initialization.
super(start, end);
}
}
您可以看到,ThreeGradient
依赖于其父级Gradient
中的数据,这是它应该能够做到的。如果其父级渐变未初始化,则它将无法正常工作。这是一个假设性的讨论,因为Java中不允许这样做 这应该是可行的,唯一的例外是必须首先在BeginChecker
构造函数中调用super
。protected
关键字允许所有子类访问其父类受保护的方法/变量。还要注意,构造函数用于初始化对象。它不是向用户打印文本的地方。@Pphoenix谢谢,但我想知道为什么super应该是第一个语句?@M.s.当您创建一个从另一个类继承的对象时,首先创建父类。这就是java所决定的,可能有一个很好的理由(尽管我不知道是什么原因)。因此,您只有一行可以调用父类构造函数,因为在第一行构造函数之后创建了父类。这样,在子类开始初始化之前,父对象始终处于可用状态。这样子类就不会意外地打乱初始化顺序,并在父类中使用尚未准备好的东西。这应该可以工作,唯一的例外是必须首先在BeginChecker
构造函数中调用super
。protected
关键字允许所有子类访问其父类受保护的方法/变量。还要注意,构造函数用于初始化对象。它不是向用户打印文本的地方。@Pphoenix谢谢,但我想知道为什么super应该是第一个语句?@M.s.当您创建一个从另一个类继承的对象时,首先创建父类。这就是java所决定的,可能有一个很好的理由(尽管我不知道是什么原因)。因此,您只有一行可以调用父类构造函数,因为在第一行构造函数之后创建了父类。这样,在子类开始初始化之前,父对象始终处于可用状态。这样子类就不会意外地打乱初始化顺序,并在父类中使用尚未准备好的东西。这应该可以工作,唯一的例外是必须首先在BeginChecker
构造函数中调用super
。受保护
keywo