I was able to pass a secret test with my code, which essentially test the code with certain input and expected output. I kept getting an assertion error which stated, expected<1> but was:<0> Until I changed the code from this:
public Gunner(){
this.gunpower = 1;
this.GunnerStrength = 1;
this.name = "Default Gunner";
}
to
public Gunner() {
this("Default Gunner", 1, 1);
}
To illustrate further and to give reference points, here are the codes which preceded the above code:
package ship;
public class Gunner {
private String name;
private int gunpower;
private int GunnerStrength;
private int maxGupower;
private int maxGunnerStrength;
private int currentGunpower;
private int currentGunnerStrength;
public Gunner(String l_name, int l_gunpower, int l_GunnerStrength) {
this.name = l_name;
this.currentGunpower = maxGunpower = l_gunpower;
this.currentGunnerstrength = maxGunnerStrength = l_GunnerStrength;
}
public Gunner(Gunner other) {
this.name = new String(other.name);
this.gunpower = new Integer(other.gunpower);
this.GunnerStrength = new Integer(other.GunnerStrength);
this.maxGunpower = new Integer(other.maxGunpower);
this.maxGunnerStrength = new Integer(other.maxGunnerStrength);
this.currentGunpower = new Integer(other.currentGunpower);
this.currentGunnerStrength = new Integer(other.currentGunnerStrength);
}
}
If someone could please explain the differences between the two codes above it would be much appreciated.
Your original Gunner() constructor attempted to duplicate the logic of the Gunner(String,int,int) constructor, although apparently (as you've passed whatever the "secret test" was), it failed to do so correctly since it filled in different fields: It initialized gunpower, GunnerStrength, and name; but the other constructor initializes name, currentGunpower, maxGunpower, currentGunnerStrength, and maxGunnerStrength. That's quite a different set of fields.
Your revised Gunner() constructor reuses the logic of the Gunner(String,int,int) constructor, rather than attempting to duplicate it. And so it fills in the fields that Gunner(String,int,int) fills in. Presumably the test expected those fields to be filled in.
In general, duplicating logic is a bad idea, because inevitably things change over time, so unless there are convincing arguments to the contrary, reusing rather than duplicating logic is the way to go.
Re your edit:
I kept getting an assertion error which stated, expected<1> but was:<0>
The default value of an int field is 0, so if you don't initialize or assign another value to the field, it will have the value 0. So presumably the unit test was checking the value of one of the fields your original Gunner() didn't fill in (currentGunpower, maxGunpower, currentGunnerStrength, or maxGunnerStrength) but your new Gunner() does fill in (via Gunner(String,int,int)).
Side note:
Difference between using these two default constructors?
There are no default constructors in your code. A default constructor is provided by the compiler if you don't define any constructors for the class. Since you do define constructors for the class, there is no default constructor.
Your Gunner() constructor is a constructor with no formal parameters, sometimes called a zero-params constructor or a zero-args constructor or a no-arg(s) constructor (Java uses "parameter" rather than "argument" to refer to the things you pass into methods and constructors, but they're also commonly called "arguments" informally, hence "args").
Related
I have noticed a thing that a constructor and a simple method of a class do the same work. what is the exact reason to create a construct of a class? If i create MyClass(){} constructor and MyClassMethod(){} method it will do the same work as I write the body part of those method and constructor. So what is the need of construct? Does it have any special use ?
A constructor and a method are two different things. The fact that you can write the same or similar code inside them is irrelevant.
When a new object is created a constructor is called. If you don't specify one the compiler will create a default one for you. This is the place where initializaton of the object's fields takes place and memory is allocated for the object. This is a concept that all object-oriented languages have. A new object must be initialized somehow. Memory needs to be allocated. In Java you don't manage the memory yourself (at least not directly anyway) so this is the purpose of the constructor. Note that since a constructor is always executed, this behaviour is enforced as soon as you call e.g. Person p = new Person();.
Now since a constructor is always being called, you have an option here: do you let the default constructor execute or do you create one yourself? Perhaps there are fields that need to be initialized in a way other than their default values. Or perhaps you need to not allow creating an object without providing some values. If you define a constructor yourself, the compiler does not create a default one for you. So if I have public Person(String firstName, String lastName) {} then I have created a specific rule that is again enforced by the system: a new object of class Person cannot be created unless you give a first name and last name:
Person p = new Person(); // this would give a compile error
Person p = new Person("John", "Smith"); // this is the only way to create an object now
Using a method you cannot enforce this. The programmer using your class might call your method or not. The constructor is a part of the lifecycle of the object. Methods define the behaviour of the object
Some points :
1) Constructors are the only way to set final instance variables .
public class SomeType {
final int x ;
SomeType(int y){
x=y;
}
}
2) A class with private constructor cannot be sub classed.
3) If your class is a subclass and the base class doesn't have a default constructor , then you need a constructor in your class to call the super class constructor.
One of the benefits of using a constructor over a method is that you can be assured the constructor was called and the work within the constructor was performed.
The language specifies that to construct an object a constructor must be called. So if you use a custom method to establish the initial state of your object, you will need to call the default constructor first. Why make two method calls when you can perform the work in one call the constructor and be assured the object has been properly initialized?
public class Test(){
private Integer x;
public Test(){
}
public Test(Integer x){
this.x = x;
}
public void setX(Integer x){
this.x = x;
}
public void doSomethingWithX(){
this.x.toString();
}
}
Test test = new Test(8);
test.doSomethingWithX(); //I know x has been declared and assigned
Test test = new Test();
test.doSomethingWithX(); //X has not been assigned results in NPE
If you create a new Object of MyClass it will automatically call the constructor - you can initialize all members within it, and be sure that this object´s members are all initialized.
Generally:
A constructor is always called once when you create a new Object of this class, and you can´t call it manually.
And don´t do "real" work in a constructor, as it will slow down the creation of objects of this class - only initialize your class/members there.
You can also use different constructors, depending on your needs - but if you create a constructor, there is no more default constructor!
Example:
public MyClass {
int score;
public MyClass(int sc) { // already know the score
score = sc;
}
public MyClass() { // don´t know the score yet
score = 1;
}
public void addScore() {
score += 5; // i know for sure that score is not zero
}
}
Essentially a constructor is just a special method that implicitly returns an object of its containing type. You should generally use constructors for creating objects - this is what people expect to see.
However, there is a useful idiom called the factory method (more info at this link) which is essentially using a static method to construct an object, the key advantages being
You can give a factory method a more descriptive name (whereas of course a standard constructor has to be named after the containing class).
They don't have to return an object, giving more flexibility.
They can return a sub-types of the class.
You can set final fields without initializer in a constructor. This helps to build immutable instances:
class Number extends Expr {
private final int n;
public Number(int n) {
this.n = n;
}
public int getValue() {
return this.n;
}
}
So after a constructor like this, you can rely on the fact that the instance is initialized completely (and in this case, it's values are immutable/constant).
Constructor is not like simple methods. It is called every time when the object of that particular class is created. You don't need to call it explicitly.
There are somethings that we need to do immediately when the object is created, for instance when you create a GUI kind of thing you want to set many properties on the time of creation like size of window etc.
Another benefit of constructor is security of class. You cannot create a object unless you know the right perimeters of constructor.
More details:http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
A constructor is a special method of a class or structure in object-oriented programming that initializes an object of that type.
Some points :
1. A constructor eliminates placing the default values.
2. A constructor eliminates calling the normal method implicitly.
These are the benefits of constructors.
Automatic initialization of objects at the time of their declaration.
Multiple ways to initialize objects according to the number of
arguments passes while declaration.
The objects of child class can be initialised by the constructors of base class.
This question already has answers here:
How to avoid constructor code redundancy in Java?
(4 answers)
Closed 9 years ago.
Hi I am just learning about constructor chaining in Java and had some questions...
First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.
In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?
import java.util.*;
class Employee
{
private String name;
private double salary;
public Employee()
{
this("James Bond", 34000);
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public static void main(String[] args)
{
Employee a = new Employee();
}
}
Actually I believe the most common use of chained Constructors is when the Constructor does more than just setting the member variables.
static int numOfExamples = 0;
public Example(String name, int num)
{
this.name = name;
this.num = num;
numOfExamples++;
System.out.println("Constructor called.");
Log.info("Constructor called");
}
public Example()
{
this("James Bond",3);
}
That way we don't have to write the code for logging and incrementing the static variable twice, instead just chaining the constructors.
Chaining constructors like this is useful to avoid repeating code, and helps with maintainability:
public MyClass(int x, double y, String z) {
// set fields
}
public MyClass() { // i.e. a constructor that uses default values
this(42, 4.2, "hello world"); // x is 42, y is 4.2, and z is "hello world"
}
If we didn't use the chain, and wanted to change how the x argument (for example) is processed when constructing an instance of MyClass, we would have to change code in both constructors. With the chain, we only need to change one of them.
1) As others have said, it's for code maintenance, basically the idea is that you only write one piece of code once, which means you only need to edit it once, there is no risk of overlooking something when editing your methods and the two accidentally becoming different.
Personally I tend to use this differently than in your example. Like so:
Employee() {
setupStuff();
}
Employee(String name) {
this();
this.setName(name);
}
This is a nice way of doing things, because potentially your setter can be way more complicated than just setting a member in the class. So basically what this does is puts calling the empty constructor and then a setter into a single method, making it much easier for anyone using the class.
2) The constructor being called doesnt't create a different object at all, it creates this object. Note that there is no new keyword used. Basically you're just calling a different method inside your constructor, except that method happens to also be a constructor.
Every time you want to allow constructing an object wit default values, and also want to allow creating the same object with non-default values. Let's imagine a DateTime class. You could want to initialize it with the current time by default, or with a specific time. Imagine a Car class. You could imagine constructing it with Black as the default color, or with a specific color. This kind of situation is very common. See java.util.ArrayList or java.util.Locale, for concrete examples.
It's stored in the name field. So you access it, from the object itself, with this.name (this being optional, just as in the getName() method).
How do I access this new "James Bond" object for future use?
Because you saved the values of name and salary as fields of your employee class, then inside the employee class you can use those fields, and outside your employee class you can use the getter/setter methos of your employee class
fairly new to this language. Long time lurker, first time question asker.
In my program, I load a bunch of strings from a text file and then pass all of that information inside of a String array to a program that takes the data point by point (it comes in a reliable pattern) and assigns it to variables inside a class.
I use this loop to create the objects.
Gladiator[] gladiator = new Gladiator[(match.contestants)];
for ( int a = 0; a < match.contestants; a++) {
gladiator[a] = new Gladiator();
gladiator[a].populategladiators(parsedInfo,a);
}
Gladiator class full of public final variables which are defined in the method populategladiators. The syntax is as follows:
this.name = parsedInfo[0+mod][0];
this.culture = parsedInfo[1+mod][0];
this.background = parsedInfo[2+mod][0];
etc.
At the moment, I only load two gladiators and it seems like maybe both are being set at once with both pass throughs? Anyone have any thoughts on this?
Also, in another method in class Gladiator, should I be able to call this.name and be okay to get data about the object I specified when calling the method?
Edit: Trying to make the code look right. Giving up since there isn't much.
2nd Edit: Example of variable declaration in gladiator class:
public static String name;
public static String culture;
public static String background;
I had my variables set as static, thus it wasn't allowing me to set individual variables for the objects. I just didn't understand what the static keyword meant.
public class Country implements ICountry {
int stability = 2;
}
Country poland = new Country(stability = 3);
What I'm trying to do is extend an interface(ICountry) with a new class("Country") that has a few default values. I want to know if it's possible to redefine some of those defaults when creating a new instance of the Country class. The last line of code in my example is what I currently have as my attempt to accomplish this, but my IDE is warning me that 'stability cannot be resolved to a variable'.
My questions is, is it possible to redefine some of an object's default values when instantiating a class without constructing a method?
I'm just starting to learn Java and Android programming on my own, so if you think I referred to something with the wrong terminology please correct me.
What you want is to define a constructor of Country that accepts a parameter and assigns it to a field, like so:
public class Country implements ICountry {
int stability = 2; // the default
public Country() {
// no parameters, no assignments
}
public Country(int stability) {
// declares parameter, assigns to field
this.stability = stability;
}
}
You can then create multiple instances of this class, like this:
Country unitedKingdom = new Country(); // 2 is the value of stability, taken from the default
Country poland = new Country(3); // 3 is the value of stability
The reason you need to have two constructors is that the version with no parameters (the "default", or "implicit" constructor) is generated if you haven't specified one, but once you specify a constructor, it won't be generated any more.
An alternate, and equivalent syntax for the default constructor could be:
public class Country implements ICountry {
int stability; // declare field, but don't assign a value here
public Country() {
this.stability = 2; // instead assign here, this is equivalent
}
}
Both this version and the previous version of the default constructor result in the same effect, but is generally a matter of preference.
There are languages that use the syntax you have shown, they're called "named parameters", but Java doesn't have them.
This is what overloaded constructors are for:
public Country(int stability)
{
this.stability=stability;
}
Feels like a super basic question, but I can't wrap my head around it.
There is a class PriceGroup, with no constructor of whom I'm making an object of.
class SmallPortfolio{
String id;
// all the investments (stocks) belonging to this portfolio.
List<Investment> invList = new ArrayList<Investment>();
}
Now in a separate class, I'm creating a SmallPortfolio object named Spor.
//
String id = InstanceID.getTextNormalize(); //this value is taken from an element from jdom.
SmallPortfolio Spor;
Spor.id = id;
//some code that creates a list of investments
//some code that creates a list of SmallPortfolio objects
In java, how do you give a null object's field a value getting by the NullPointerException?
An alternate solution would be somehow declaring a SmallPortfolio object that wasn't null.
It's a strange problem, but the test program I'm using cannot be modified and it has no constructors for SmallPortfolio.
Unless you define some constructors yourself, Java will automatically create a default no-argument constructor for you. So you can write:
SmallPortfolio smallPort = new SmallPortfolio();
However, in your case, the author of the SmallPortfolio class should probably have provided an ad-hoc constructor:
class SmallPortfolio{
private final String id;
// all the investments (stocks) belonging to this portfolio.
private final List<Investment> investments = new ArrayList<Investment>();
public SmallPortfolio(String id) {
this.id = id;
}
//getters + methods to add / remove investments
}
All you need to do is initialize Spor:
SmallPortfolio Spor = new SmallPortfolio();
This will create a non-null object. Also, if you're going to be adding an id to it after each initialization, you may as well add that to the constructor. Hope that helps!
Spor is never initialized:
SmallPortfolio Spor;
replace with:
SmallPortfolio Spor = new SmallPortfolio();
Question is a bit unclear, but if you are asking if you can assign fields or call methods on the null object, then, no, you cannot. You need to have (or make) an instance of your class.
SmallPortfolio Spor = new SmallPortfolio();
Spor.id = id;
The code you have shown above should not even compile, because you have not assigned a value (not even null) to Spor. (If you do assign null, you'll get a runtime nullpointer exception).
If the confusion was how to make an object when there is no constructor: In this case, there is one, because if the Java code does not specify any constructor (but only then), there is an automatic default constructor that does not need arguments.