为什么我需要抽象 class 中的构造函数?
Why do i need a constructor in an abstract class?
我目前正在学习 java 教程,向我介绍抽象 classes 并使用 J-Unit 进行测试。
我有 2 个文件,AthleteTest 和 BikerTest,BikerTest 扩展 AthleteTest.AthleteTest 包含我不同测试的常用方法和变量,而 BikerTest 包含细节。
运动员测试
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public abstract class AthleteTest
{
private Athlete a1;
private Athlete a2;
protected String _name = "Test Athlete";
protected int _age = 32;
protected int _racerId = 987654;
public abstract Athlete getAthlete();
public abstract Athlete getExplicitAthlete();
public AthleteTest()
{
a1 = getAthlete();
a2 = getExplicitAthlete();
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testConstructors()
{
assertNotNull("Default Runner could not be created", a1);
assertNotNull("Explicit Runner could not be created", a2);
assertEquals("Name not set correctly on a2"
, _name
, a2.getName());
assertEquals("Age not set correctly on a2"
, _age
, a2.getAge());
assertEquals("RacerID not set correctly on a2"
, _racerId
, a2.getRacerId());
}
@Test
public void testGetSetName()
{
a1.setName(_name);
assertEquals("The name could not be set as expected"
, _name
, a1.getName());
}
@Test
public void testGetSetAge()
{
a1.setAge(_age);
assertEquals("The age could not be set as expected"
, _age
, a1.getAge());
}
@Test
public void testGetSetRacerId()
{
a1.setRacerId(_racerId);
assertEquals("The racerId could not be set as expected"
, _racerId
, a1.getRacerId());
}
public abstract void testPerformRaceActivity();
@Test
public void testToString()
{
a1.setName(_name);
a1.setAge(_age);
a1.setRacerId(_racerId);
String rts = a1.toString();
assertTrue("To String does not contain name"
, rts.contains(_name));
assertTrue("To String does not contain age"
, rts.contains(String.format("%d", _age)));
assertTrue("To String does not contain racer id"
, rts.contains(String.format("%d", _racerId)));
String rc = a1.getClass().toString();
assertTrue("To String does not contain class"
, rts.contains(rc));
}
}
自行车测试
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class BikerTest extends AthleteTest
{
private Biker r;
private String raceActivity = "Biking";
private boolean usesClips = false;
@Override
public Athlete getAthlete() {
return new Biker();
}
@Override
public Athlete getExplicitAthlete() {
return new Biker(_name,_age,_racerId,usesClips);
}
@Before
public void setUp()
{
r = new Biker();
}
@After
public void tearDown()
{
r = null;
}
@Test
public void testConstructors()
{
super.testConstructors();
Biker r2 = new Biker(_name, _age, _racerId, usesClips);
assertNotNull("Explicit Biker could not be created", r2);
assertEquals("Name not set correctly on R2"
, _name
, r2.getName());
assertEquals("Age not set correctly on R2"
, _age
, r2.getAge());
assertEquals("RacerID not set correctly on R2"
, _racerId
, r2.getRacerId());
assertEquals("UsesClips not set correctly on R2"
, usesClips
, r2.getUsingClips());
}
@Test
public void testGetSetUsingClips()
{
r.setUsingClips(usesClips);
assertEquals("The clips could not be set as expected"
, usesClips
, r.getUsingClips());
}
@Test
public void testPerformRaceActivity()
{
String pra = r.performRaceActivity();
assertTrue("Perform race activity did not contain activity"
, pra.contains(raceActivity));
}
@Test
public void testToString()
{
super.testToString();
r.setName(_name);
r.setAge(_age);
r.setRacerId(_racerId);
r.setUsingClips(usesClips);
String rts = r.toString();
assertTrue("To String does not contain using clips"
, rts.contains(String.format("%b", usesClips)));
assertTrue("To string does not contain performRaceActivity"
, rts.contains(raceActivity));
}
}
现在,虽然我的文件和代码正在运行(它取自所提供的示例),但我无法弄清楚为什么它会运行,因为教程没有详细介绍如何执行测试。
QN1
为什么我在抽象 class AthleteTest 中需要一个构造函数?我的理解是,因为它是抽象的,它不会被实例化,因此不需要构造函数,因为构造函数仅在 class 被实例化。
QN2
测试是如何完成的;测试顺序是什么样的?例如,当我 运行 BikerTest 时,虽然我覆盖了 GetAthlete 和 GetExplicitAthlete classes,但我实际上并没有 运行 code.Yet 中的方法,为什么当我 运行代码,方法是运行。默认情况下,JUnit 是否只是 运行 所有方法?
QN3
当我 运行 BikerTest 时,superclass AthleteTest 是如何实例化和工作的?例如,在 BikerTest 中,我调用了 super - 这是 AthleteTest.Is AthleteTest 在我调用 super 时实例化/创建的 - 结果对象存储在 a1 和 a2 中,或者它是在某个时候创建的还有其他地方?
提前感谢您提供的任何澄清和解释!
Why do i need a constructor in the abstract class AthleteTest?My
understanding is that because it is abstract, it will not be
instantiated, therefore there is no need for a constructor as
constructors only come into play when the class is instantiated.
抽象 classes 不能 直接实例化 - 它们必须由非抽象 class 子class,并且subclass 可以被实例化。但是当你实例化一个subclass时,superclass的所有字段也是你创建的对象的一部分。而且,调用了抽象 superclass 的构造函数。
How is the testing done; what is the testing order like ? For
example,when i run BikerTest, while i override the GetAthlete and
GetExplicitAthlete classes, i do not actually run the methods in the
code.Yet why is it when i run the code, the methods are run. Does
JUnit simply run all methods by default?
当你运行一个class作为JUnit 4的测试时,所有用@Test注释的方法都是运行作为测试方法。 @Before注解的方法是运行每次测试前运行,@After注解的是每次测试后
您可以使用更多的注解,例如@BeforeClass 和@AfterClass。
How is the superclass AthleteTest instantiated and work when i run
BikerTest? For example, in BikerTest, i made calls to super - which is
AthleteTest.Is AthleteTest instantiated/ created at the point when i
make a call to super - and the resulting object is stored in a1 & a2,
or is it created somewhen and somewhere else?
不,superclass 在您实例化 subclass 时被实例化。实际上,您创建了一个对象,该对象包含您实例化 的 subclass 及其所有 superclasses 的所有字段。因此,当 JUnit 为您创建 BikerTest
的实例时,AthleteTest
中的所有字段(作为 BikerTest
的超级 class 也作为对象的一部分创建。构造函数AthleteTest
的也被调用。
Why do i need a constructor in the abstract class AthleteTest?My understanding is that because it is abstract, it will not be instantiated
没错。无法实例化抽象 class。虽然,这并不意味着抽象 classes 不能有构造函数。如果您不向 class 添加构造函数,编译器将为您添加一个默认的无参数构造函数。对于 abstract classes 也是如此。此外,Java 中的每个构造函数都有一个隐式的 super()
调用,因为它的第一行调用父 class 的构造函数(包括编译器添加的默认构造函数)。在您的示例中, BikerTest
没有显式构造函数。因此,编译器会将以下构造函数添加到 BikerTest
class :
public BikerTest() {
super();
}
一旦您 运行 BikerTest
JUnit
class, JUnit
创建 BikerTest
[=51= 的实例] 和 BikerTest
构造函数中的 super()
调用将导致调用 AthleteTest
class 的构造函数。
For example,when i run BikerTest, while i override the GetAthlete and
GetExplicitAthlete classes, i do not actually run the methods in the
code.Yet why is it when i run the code, the methods are run
如前所述,BikerTest
中的 super()
调用导致调用 AtheleteTest
class 的无参数构造函数。 AtheleteTest
class 调用 getAthlete()
和 getExplicitAthlete()
方法。虽然这些方法是抽象的,但它们已在 BikerTest
class 中被覆盖。 BikerTest
class 中的方法将被调用,因为创建的对象属于 class BikerTest
How is the superclass AthleteTest instantiated and work when i run
BikerTest? For example, in BikerTest, i made calls to super - which is
AthleteTest.Is AthleteTest instantiated/ created at the point when i
make a call to super - and the resulting object is stored in a1 & a2,
or is it created somewhen and somewhere else?
没有。使用 super
调用方法或使用 super
访问字段不会导致超级 class 被实例化(无论它是否是抽象的)。 r
变量在 setUp
方法中分配了一个对象,这是 JUnit
在 运行 任何测试之前调用的第一个方法。 a1
和 a2
变量在实例化 BikerTest
并调用 AtheleteTest
无参数构造函数时被分配一个对象(如前所述)
抽象 class 中的构造函数可用于初始化您的 class 例如,如果您使用 final 属性。并且您的 subclass 的构造函数可以调用抽象 class.
的一个构造函数
我目前正在学习 java 教程,向我介绍抽象 classes 并使用 J-Unit 进行测试。
我有 2 个文件,AthleteTest 和 BikerTest,BikerTest 扩展 AthleteTest.AthleteTest 包含我不同测试的常用方法和变量,而 BikerTest 包含细节。
运动员测试
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public abstract class AthleteTest
{
private Athlete a1;
private Athlete a2;
protected String _name = "Test Athlete";
protected int _age = 32;
protected int _racerId = 987654;
public abstract Athlete getAthlete();
public abstract Athlete getExplicitAthlete();
public AthleteTest()
{
a1 = getAthlete();
a2 = getExplicitAthlete();
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testConstructors()
{
assertNotNull("Default Runner could not be created", a1);
assertNotNull("Explicit Runner could not be created", a2);
assertEquals("Name not set correctly on a2"
, _name
, a2.getName());
assertEquals("Age not set correctly on a2"
, _age
, a2.getAge());
assertEquals("RacerID not set correctly on a2"
, _racerId
, a2.getRacerId());
}
@Test
public void testGetSetName()
{
a1.setName(_name);
assertEquals("The name could not be set as expected"
, _name
, a1.getName());
}
@Test
public void testGetSetAge()
{
a1.setAge(_age);
assertEquals("The age could not be set as expected"
, _age
, a1.getAge());
}
@Test
public void testGetSetRacerId()
{
a1.setRacerId(_racerId);
assertEquals("The racerId could not be set as expected"
, _racerId
, a1.getRacerId());
}
public abstract void testPerformRaceActivity();
@Test
public void testToString()
{
a1.setName(_name);
a1.setAge(_age);
a1.setRacerId(_racerId);
String rts = a1.toString();
assertTrue("To String does not contain name"
, rts.contains(_name));
assertTrue("To String does not contain age"
, rts.contains(String.format("%d", _age)));
assertTrue("To String does not contain racer id"
, rts.contains(String.format("%d", _racerId)));
String rc = a1.getClass().toString();
assertTrue("To String does not contain class"
, rts.contains(rc));
}
}
自行车测试
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class BikerTest extends AthleteTest
{
private Biker r;
private String raceActivity = "Biking";
private boolean usesClips = false;
@Override
public Athlete getAthlete() {
return new Biker();
}
@Override
public Athlete getExplicitAthlete() {
return new Biker(_name,_age,_racerId,usesClips);
}
@Before
public void setUp()
{
r = new Biker();
}
@After
public void tearDown()
{
r = null;
}
@Test
public void testConstructors()
{
super.testConstructors();
Biker r2 = new Biker(_name, _age, _racerId, usesClips);
assertNotNull("Explicit Biker could not be created", r2);
assertEquals("Name not set correctly on R2"
, _name
, r2.getName());
assertEquals("Age not set correctly on R2"
, _age
, r2.getAge());
assertEquals("RacerID not set correctly on R2"
, _racerId
, r2.getRacerId());
assertEquals("UsesClips not set correctly on R2"
, usesClips
, r2.getUsingClips());
}
@Test
public void testGetSetUsingClips()
{
r.setUsingClips(usesClips);
assertEquals("The clips could not be set as expected"
, usesClips
, r.getUsingClips());
}
@Test
public void testPerformRaceActivity()
{
String pra = r.performRaceActivity();
assertTrue("Perform race activity did not contain activity"
, pra.contains(raceActivity));
}
@Test
public void testToString()
{
super.testToString();
r.setName(_name);
r.setAge(_age);
r.setRacerId(_racerId);
r.setUsingClips(usesClips);
String rts = r.toString();
assertTrue("To String does not contain using clips"
, rts.contains(String.format("%b", usesClips)));
assertTrue("To string does not contain performRaceActivity"
, rts.contains(raceActivity));
}
}
现在,虽然我的文件和代码正在运行(它取自所提供的示例),但我无法弄清楚为什么它会运行,因为教程没有详细介绍如何执行测试。
QN1 为什么我在抽象 class AthleteTest 中需要一个构造函数?我的理解是,因为它是抽象的,它不会被实例化,因此不需要构造函数,因为构造函数仅在 class 被实例化。
QN2 测试是如何完成的;测试顺序是什么样的?例如,当我 运行 BikerTest 时,虽然我覆盖了 GetAthlete 和 GetExplicitAthlete classes,但我实际上并没有 运行 code.Yet 中的方法,为什么当我 运行代码,方法是运行。默认情况下,JUnit 是否只是 运行 所有方法?
QN3 当我 运行 BikerTest 时,superclass AthleteTest 是如何实例化和工作的?例如,在 BikerTest 中,我调用了 super - 这是 AthleteTest.Is AthleteTest 在我调用 super 时实例化/创建的 - 结果对象存储在 a1 和 a2 中,或者它是在某个时候创建的还有其他地方?
提前感谢您提供的任何澄清和解释!
Why do i need a constructor in the abstract class AthleteTest?My understanding is that because it is abstract, it will not be instantiated, therefore there is no need for a constructor as constructors only come into play when the class is instantiated.
抽象 classes 不能 直接实例化 - 它们必须由非抽象 class 子class,并且subclass 可以被实例化。但是当你实例化一个subclass时,superclass的所有字段也是你创建的对象的一部分。而且,调用了抽象 superclass 的构造函数。
How is the testing done; what is the testing order like ? For example,when i run BikerTest, while i override the GetAthlete and GetExplicitAthlete classes, i do not actually run the methods in the code.Yet why is it when i run the code, the methods are run. Does JUnit simply run all methods by default?
当你运行一个class作为JUnit 4的测试时,所有用@Test注释的方法都是运行作为测试方法。 @Before注解的方法是运行每次测试前运行,@After注解的是每次测试后
您可以使用更多的注解,例如@BeforeClass 和@AfterClass。
How is the superclass AthleteTest instantiated and work when i run BikerTest? For example, in BikerTest, i made calls to super - which is AthleteTest.Is AthleteTest instantiated/ created at the point when i make a call to super - and the resulting object is stored in a1 & a2, or is it created somewhen and somewhere else?
不,superclass 在您实例化 subclass 时被实例化。实际上,您创建了一个对象,该对象包含您实例化 的 subclass 及其所有 superclasses 的所有字段。因此,当 JUnit 为您创建 BikerTest
的实例时,AthleteTest
中的所有字段(作为 BikerTest
的超级 class 也作为对象的一部分创建。构造函数AthleteTest
的也被调用。
Why do i need a constructor in the abstract class AthleteTest?My understanding is that because it is abstract, it will not be instantiated
没错。无法实例化抽象 class。虽然,这并不意味着抽象 classes 不能有构造函数。如果您不向 class 添加构造函数,编译器将为您添加一个默认的无参数构造函数。对于 abstract classes 也是如此。此外,Java 中的每个构造函数都有一个隐式的 super()
调用,因为它的第一行调用父 class 的构造函数(包括编译器添加的默认构造函数)。在您的示例中, BikerTest
没有显式构造函数。因此,编译器会将以下构造函数添加到 BikerTest
class :
public BikerTest() {
super();
}
一旦您 运行 BikerTest
JUnit
class, JUnit
创建 BikerTest
[=51= 的实例] 和 BikerTest
构造函数中的 super()
调用将导致调用 AthleteTest
class 的构造函数。
For example,when i run BikerTest, while i override the GetAthlete and GetExplicitAthlete classes, i do not actually run the methods in the code.Yet why is it when i run the code, the methods are run
如前所述,BikerTest
中的 super()
调用导致调用 AtheleteTest
class 的无参数构造函数。 AtheleteTest
class 调用 getAthlete()
和 getExplicitAthlete()
方法。虽然这些方法是抽象的,但它们已在 BikerTest
class 中被覆盖。 BikerTest
class 中的方法将被调用,因为创建的对象属于 class BikerTest
How is the superclass AthleteTest instantiated and work when i run BikerTest? For example, in BikerTest, i made calls to super - which is AthleteTest.Is AthleteTest instantiated/ created at the point when i make a call to super - and the resulting object is stored in a1 & a2, or is it created somewhen and somewhere else?
没有。使用 super
调用方法或使用 super
访问字段不会导致超级 class 被实例化(无论它是否是抽象的)。 r
变量在 setUp
方法中分配了一个对象,这是 JUnit
在 运行 任何测试之前调用的第一个方法。 a1
和 a2
变量在实例化 BikerTest
并调用 AtheleteTest
无参数构造函数时被分配一个对象(如前所述)
抽象 class 中的构造函数可用于初始化您的 class 例如,如果您使用 final 属性。并且您的 subclass 的构造函数可以调用抽象 class.
的一个构造函数