I have a subclass "shopStaff" within class "staff". I have a meathod getPerson which I need to send the data set in staff and the data set in shopStaff as a single string.
This is my code
// in staff
public String getPerson()
{
return format(name) + format(yearJoined);
}
// in shopStaff
public String getPerson()
{
super.getPerson();
return format(department);
}
however, when I invoke the getPerson meathod in the subclass it only returns the department information, not the name and yearjoined (that I only set in the superclass.
I thought when I used the super. meathod it would return everything from the class above in the hierarchy. Is this not the case? If not could anyone tell me how I access the information set in the superclass?
Thanks
CJ
When you call:
super.getPerson();
The return is discarded as it is not stored anywhere. You'd want to do this:
//in shopStaff
public String getPerson() {
return super.getPerson() + format(department);
}
Your return value from super.getPerson() is not returned with the return statement in your current getPerson() method. It is just lost in your code.
You need to change your shopStaff method to return the super class values with your subclass return statement: -
public String getPerson()
{
return super.getPerson() + format(department);
}
public String getPerson()
{
String fromSuper=super.getPerson();
return fromSuper + format(department);
}
Just calling super will not get data unless you read and use it in subclass.
May be something like this will work:
public String getPerson()
{
String person = super.getPerson();
return person+format(department);
}
Related
I have those lines of code:
public String getAccountType(BankAccount a){
if(a instanceof RegularAccount)
return "RA";
else if(a instanceof SavingsAccount)
return "SA";
else if(a instanceof cityAccount)
return "CLA";
else if(a instanceof StateLawAccount)
return "SLA";
else if(a instanceof FederationLawAccount)
return "FLA";
else
return null;
}
BankAccount is the super class (abstract) of all classes below. In this method, I just want to return what "a" class is within a String.
But, I was wondering if there is a better way to verify "a" class other than this bunch of if/else statements. Is there one? Could I do it with switch statement? If so, how?
Put an abstract method getAccountType() on BankAccount, and then have the implementations return the account type string. Here's an example that assumes that BankAccount is an interface:
public interface BankAccount {
String getAccountType();
... whatever else ...
}
Then
public class RegularAccount implements BankAccount {
#Override
public String getAccountType() { return "RA"; }
... whatever else ...
}
If BankAccount is a class then just make it an abstract method.
In your case, I'd add an abstract method getAccountType () to the BackAccount class, and implement it in each concrete class so that they return the correct account type.
public abstract class BankAccount {
public abstract String getAccountType ();
// Rest of implementation
}
public class RegularAccount extends BankAccount {
private static final String ACCOUNT_TYPE = "RA";
#Override
public String getACcountType () {
return ACCOUNT_TYPE;
}
// Rest of implementation
}
There is no easier way to compare an object's class than the code example you have provided with your question. However, if you end up having to do this in your code, then you should review your current design.
Consider the case where your manager asks you to add two additional back account types (AccountX and AccountY), and asks you to remove the StateLawAccount (for some reasons). Not only do you have to add the new classes in your code for account types AccountX and AccountY and remove the existing StateLawAccount, but you also have to remember that this unrelated class has this huge if/else that checks for bank account types. If you forget about it, then you have inserted a new bug in your software.
Put a string class member in the abstract class and override its getter method in the implementation to return specific type:
public abstract class BankAccount{
String accountType;
public abstract String getAccountType(){
return accountType;
}
}
I have a class called Test and a class called SubTest who extends Text, I would like to have a method in the Test class who will returns the instance of SubTest when called, I would like to do :
SubTest test = new SubTest().setTest("Hello!").setOtherTest("Hi!");
The setTest() and setOtherTest() methods should be in the Test class.
But when I do :
public Test setTest(String test) { return this; }
It only returns the instance of Test so I have to cast Test to SubTest, but I don't want to.
Is it possible ? If yes, how ?
Thanks, MinusKube.
Having a method return its owner (this) to be able to 'chain' multiple method calls is called fluent API. You can solve your problem by using generics, although the resulting code might be somehow less readable though:
public class Person<T extends Person<T>> {
public T setName(String name) {
// do anything
return (T)this;
}
}
public class Student extends Person<Student> {
public Student setStudentId(String id) {
// do anything
return this;
}
}
public class Teacher extends Person<Teacher> {
public Teacher setParkingLotId(int id) {
// do anything
return this;
}
}
Now, you do not need any casts:
Student s = new Student().setName("Jessy").setStudentId("1234");
Teacher t = new Teacher().setName("Walter").setParkingLotId(17);
See also: Using Generics To Build Fluent API's In Java
It is possible to have those methods return a SubTest, because Java's return types are covariant.
You must override those methods so that you can return this, a SubTest, in SubTest, e.g.:
#Override
public SubTest setTest(String message) {
super.setTest(message); // same functionality
return this;
}
I have this issue with my code.
I create a class Employee with two instance variables:
private String name, department;
And afterwards I create another class called Tradesman whichc is an extension of Employee, but with one extra instance variable:
private String trade;
Now what I did is I created a print() method that will: A) in Employee class, print the name and department. B) same method used in Employee, will be created in Tradesman (thus overriding it) that will print extra one element which is the trade. Now the thing is that I create another class called Staff which will contain an array of type Object of some elements, and I have to implement a hire() method, fire() method and a put() method which will print the entire array. Everything is cool and wicked up till the moment of printing. I'm struggling with how to print it, since I have print() method for each class but it must be dependedn on the type... If i cast the method to Employee I will lose the trade element of Tradesman Class, ex:
void put(){
for (Object a:objArray){
((Employee)a).print();
}
}
Which is WRONG. Cause if I hire a Tradesman, this method won't print the Trade. How to deal with this problem? Thanks in advance! Cheers ^^
"Cause if I hire a Tradesman, this method won't print the Trade"
You're wrong, it will. If Employee is actually a Tradesman, calling print() will call Tradesman.print(). If it's overriden, then the overriding method will be called. If all your array objects are Employee, just use an Employee[] instead of Object[] so you don't have to do that useless casting.
"I want to implement an array of both Tradesman and Employee... One array that will contain both, Tradesman and Employee combined."
Employee[] will hold both since a Tradesman is an Employee. Also in Java I suggest you work with a List (List<Employee> in your case), it's more manageable than an array.
Even if you cast a Tradesman to Employee the underlying object will still be of type Tradesman and use the overridden print method.
try this
import java.util.ArrayList;
class Employee {
String name,department;
public Employee(String name, String department) {
this.name = name;
this.department = department;
}
public void print() {
System.out.println("Name: " + this.name);
System.out.println("Department: " + this.department);
}
}
class Tradesman extends Employee {
String trade;
public Tradesman(String name, String department, String trade) {
super(name,department);
this.trade = trade;
}
public void print() {
super.print();
System.out.println("Trade: " + this.trade);
}
}
class Staff {
ArrayList<Employee> empArray = new ArrayList<Employee>();
public void put() {
for(Employee emp : empArray) {
emp.print();
}
}
public static void main(String[] arg) {
Staff s = new Staff();
s.empArray.add(new Employee("John","Sales"));
s.empArray.add(new Tradesman("Jacob","Sales","Computers"));
s.put();
}
}
Consider the following enum class
public enum ClassA {
CHECK1("X", 0),
CHECK2("Y", 2),
CHECK3("Z", 1);
private final String id;
private final String cdValue;
private ClsA(String id, String cdValue) {
this.id = id;
this.cdValue = cdValue;
}
private String getId() {
return id;
}
private String getCdValue() {
return cdValue ;
}
private static final List<String> cdValues = new ArrayList<String>();
static {
for (ClassA clsA : ClassA.values()) {
cdValues.add(clsA.getCdValue());
}
}
public boolean isCdValue(String cdValue)
{
if clsValues.contains(cdValue)
return true;
else return false;
}
}
The question that I have is does the method isCdValue has to be static. I have to use this method isCdValue for every input given by the client. Therefore the method parameter cdValue changes for every input.
If it cannot be static then I would like to know how I can access this method. Please note I am primarily interested in learning about static of non-static method call. If it is a non-static call in a enum then how can we call this non static method. I am not trying to resolve the issue of how to get about checking the cdValue exists or not. It is just an example.
does the method isCdValue has to be static.
Yes, the method isCdValue has to be static here.
An enum is a special kind of class. An enum constant defines an instance of the enum type. An enum type has no instances other than those defined by its enum constants. Hence new can not be used to instantiate an enum.
An enum type has no instances other than those defined by its enum
constants. It is a compile-time error to attempt to explicitly
instantiate an enum type (ยง15.9.1).
Refer this
If you have to put the checking method in the Enum, I think it should be static
you can do this check:
ClassA.isCdValue(para)
Note that, you cannot new an Enum object. So if the method in your Enum, and it is not static, you cannot call it unless you have an Instance. but the goal of your method is checking if the string could be an instance.
another possibility is, use an immutable collection in your Enumm, and make it static and public. Then you could just call ClassA.CD_VALUES.contains(para)
If you want to access it from ClsA, you will have to make it static, if you want to access it from an instance of ClsSa then it doesn't.
A couple of other things: where do you declare clsValues in the first place?
There's no need for the complex if, you may replace this:
public boolean isCdValue(String cdValue)
{
if clsValues.contains(cdValue)
return true;
else return false;
}
with this
public boolean isCdValue(String cdValue){
return clsValues.contains(cdValue)
}
Last little thing, I'd strongly suggest you put curly braces around all your if and else's clauses, I've spent many a debugging hour because someone added a second line under the else, fooled by the indent and thinking it would only execute on the else.
You can use something like this, you do not need static List but the method has to be static as answered by Kent,
public static ClassA getClassAByCDValue(String cdValue)
{
for(ClassA value: ClassA.values())
{
if(value.cdValue.contains(cdValue))
{
return value;
}
}
return null;
}
public static boolean isCDValue(String cdValue)
{
for(ClassA value: ClassA.values())
{
if(value.cdValue.contains(cdValue))
{
return true;
}
}
return false;
}
Using above will be more appropriate as you just have to take care with adding/removing items in enum.
java n00b here.
I have a custom Data type defined like this:
public class MyData{
int value;
int type;
String name;
public MyData(int newValue, int newType, string newName)
{
value = newValue;
type = newType;
name = newName;
}
}
When I call an instance of this class, I want it to evaluate to the value property, like this:
myData dataInstance = new myData(100,3,"customData");
System.out.println(dataInstance); // should print "100"
Can this be achieved?
When you use System.out.println with an object, it's going to call the toString() method - so you just need to override that:
#Override public String toString() {
return String.valueOf(value);
}
Also note that you should be more specific in your terminology. When you wrote:
When I call an instance of this class
... that doesn't mean anything. You don't call an instance - you call a method on an instance. In this case, the method is toString.