I am reading a code which is done something like this, and I want to understand why it is doing this:
public abstract class Class2 extends Class1 {
...
#Override
public ObjectType someFunction() {
ObjectType var = super.someFunction();
....
return var;
}
}
So the someFunction() method has been overwritten and the someFunction() of the parent is called again inside it.
Does it make sense to you? What would be the motivation for doing this?
If you don't want to duplicate the code for the entire overridden method, but you want to change the logic a little bit or if you want to add a little bit of code, then you can call the overridden method and provide additional code.
This prevents duplication of code and logic in subclasses that wish to override a method but retain some behavior.
As yshavit has indicated in a comment, calling the overridden method may be the only way to access data that is private in the superclass.
Pretty usefull when you want to use inheritance properly.
Just imagine that you have a class Person which is composed by a name and a surname and you want to specify the job, like Farmer.
class Person {
private String name;
private String surname;
//... Constructor
public String getInfos() {
return this.name + " " + this.surname;
}
}
class Farmer extends Person {
//... Constructor
#Override
public String getInfos() {
return super.getInfos() + " is a farmer.";
}
}
Person p1 = new Person("Name", "Surname");
System.out.println(p1.getInfos());
// Show "name surname"
Person p2 = new Farmer("Name", "Surname");
System.out.println(p2.getInfos());
// Show "name surname is a farmer."
Related
I am having trouble with a method that accepts two classes Pokemon as its parameters because it could be whatever pokemon battling, but if I try to catch the name of the subclass, such as Totodile, the superclass's name attribute is printed
in Pokemon.java:
abstract public class Pokemon {
private String name="POKEMON";
public String getName() {
return name;
}
}
in Totodile.java :
public class Totodile extends Pokemon {
String name = "Totodile";
}
in Geodude.java :
public class Totodile extends Pokemon {
String name = "Geodude";
}
in Battle.java :
public class Battle {
public void initiateBattle(Pokemon pokemon1,Pokemon pokemon2){
System.out.println(pokemon1.getName()+ " is battling against " + pokemon2.getName());
}
}
in App.java:
public class App {
public static void main(String[] args) throws Exception {
Geodude geodude = new Geodude();
Totodile totodile = new Totodile();
Battle battle = new Battle();
battle.initiateBattle(totodile, geodude);
}
}
The output is "POKEMON is battling against POKEMON"
, but how could I get "Totodile is battling against Geodude"
You can't "override" a field. When you write:
class Foo {
String name;
}
you are always declaring a new field. If your superclass also has a field with the same name, okay. Now your Totodile class has 2 fields, both named name, one of which has value POKEMON, the other has value Totodile.
Which one do you get when you write myPokemon.name? Depends on the compile-time type of myPokemon (the variable, not the object it is pointing at!) - and given that it is Pokemon in your code, you get the Pokemon version of the name field.
This notion that you have 2 fields with identical names is called 'shadowing'.
Shadowing is a mistake; do not do it unless you really, really know what you are doing.
The solution is therefore quite simple: Don't define a field named name in the Totodile class. Instead, set the value of the name field (which you inherited, so the Totodile class has that name field already, no need to make a second field with the same name and confuse things):
class Totodile {
{ name = "Totodile"; }
}
This somewhat weird syntax creates an instance initializer, as you need to stuff your code somewhere (you can't just start putting statements straight into a class, you need to brace em up). This is a tad odd, the more usual design is instead something like this:
abstract class Pokemon {
private final String name;
public Pokemon(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Totodile extends Pokemon {
public Totodile() {
super("Totodile");
}
}
This is what most java programmers do:
It forces subclasses of Pokemon to actually set the name properly. That default 'POKEMON' value is weird and no longer needed in the above strategy.
It avoids exotic code constructs to make it work. Constructors and abstract classes tend to be a lot more familiar to your average java coder than instance initializers.
Adds final in the appropriate places.
I have quite a few getter methods in a class and I need to print the return of those getters (Just one and not all of them at once). I need to be able to do this with one print() method but I am not sure how to do this. Is there a way to dynamically call another method and then print the return of that method?
Here are a couple of getter methods:
public String getEmail()
{
return this.studentEmail;
}
public Integer getAge()
{
return this.studentAge;
}
Here is what I am wanting to do:
public void print(???)
{
System.out.println(theGetterMethod);
}
I know that I can create a bunch of print methods but I need to be able to do this with one method.
As asked by the OP:
"I think you were correct with your first comment and it can be an answer."
From:
"You can tackle it by using Sytem.out.println ("E-mail: " + ...getEmail(), " Age: " + ...getAge()); If you want to go overkill you can use reflection."
Meaning instead of having a seperate print() method you will instead be invoking the right accessor for the value you want to print.
This is one of reasons why you use accessors in the place, as now you are exposing the fields without any risk of having the user change them.
You can still change on underlying Objects apart from String as it is immutable.
You can call methods dynamically based on their name by using reflection.
In this example I assume that each Getter follows a pattern and just pass over the property name that I want to print out:
import java.lang.reflect.Method;
public class Student {
private String studentEmail = "MyEmail";
private Integer studentAge = 20;
public String getEmail() {
return this.studentEmail;
}
public Integer getAge() {
return this.studentAge;
}
// Prints out a property based on the name
public void print(String property) throws Exception {
for (Method method : this.getClass().getMethods())
if (method.getName().equals("get" + property))
System.out.println(method.invoke(this, null));
}
// Prints out all properties with a getter
public void print() throws Exception {
for (Method method : this.getClass().getMethods())
if (method.getName().startsWith("get"))
System.out.println(method.invoke(this, null));
}
}
And than call the method like that:
Student s = new Student();
s.print("Email");
s.print("Age");
Interface :
public interface Person {
public String name = "";
}
I have two classes:
public class Male implements Person {
public String name = "Male1";
}
Another class being
public class Female implements Person {
public String name = "Female";
}
I want to instantiate a class at runtime depending on who the user is. Something like :
Person p = getPerson("M");
System.out.println("P = " + p.name);
private static Person getPerson(String gender) {
if (gender.equals("M"))
return new Male();
else if (gender.equals("F"))
return new Female();
else
return null;
}
I am expecting the output to be: Male1
How can I achieve this ? What is the best design pattern to achieve this functionality ?
lookup and use Class.forName()
You don't put attributes in an interface.
Your interface should include a String getName(); method signature. Then you implement this method in all inherited classes. That way, you can call getName() on your Person object to retrieve the person's name regardless of the implementation class.
To instantiate, take a look at the Factory pattern.
There are several options, but you could use Abstract Factory:
Create a PersonFactory interface with just a createPerson method. Then make two implementations:
MaleFactory which returns a new Male
FemaleFactory which returns a new Female
Then keep a Map<String, PersonFactory> where the key is the gender and the value is an instance of the factory that will create the appropriate Person instances.
Getting a new Person given the gender becomes as simple as
map.get(gender).createPerson()
EDIT:
I see you have edited your question so that it now includes a question about using variables in interfaces.
Basically, you don't want to put the variable in the interface, because that will mean it's static (the static keyword is implied in this case since interfaces can't have non-static variables), and I guess you don't want all persons to have the same name.
So you'll have to declare a getName() method in the interface. If the behaviour should be the same for all genders (I don't see why not) then you can just put both the name variable and the getName() method in an abstract base class (e.g. AbstractPerson) which both Male and Female extend.
I have these two classes:
class Parent
{
protected static String table;
public static long getRow()
{
String query = "SELECT * FROM " + table + " WHERE id =? " ;
//other code...
}
}
I then extend this class :
class Child extends Parent
{
protected static String table = "tableName";
//other code..
}
However, when I try to do this:
long id = Child.getRow();
I get an error, because the query is getting "null" put in it where the value of table should be. I.e SELECT * FROM null.
I thought that setting the value of table in the child class would cause it to be updated in the methods it inherits as well, but apparently not. What do I need to do to fix this?
You cannot override variables this way. In your example, each class has its own version of the table variable, and in the Parent, where the getRow method is defined, the variable is undefined. Here's a better design you can use:
abstract class Parent {
public abstract String getTable();
public static long getRow() {
String query = String.format("SELECT * FROM %s WHERE id = ?", getTable()) ;
//other code...
}
}
class Child extends Parent {
public String getTable() {
return "tableName";
}
}
instance variables(also static variables) are not overridden in your subclass. they are only visible in your subclass if they are marked as protected, public or default. polymorphism and inheritence doesn't apply to instance variable. for your code to work the only option is to make your getRow() method public override it in your subclass
Replace the naked field access with a getter/setter method.
When you override the getter/setter in the subclass, then you are given control over what variable it reads to and writes.
Java does not provide this level of control over field access.
Just one little thing. Inside a method you can access an shadowed field with super. If you place this code in the Child class:
public void foo() {
this.table="this belongs to the child";
super.table="this belongs to the parent";
}
note that this.table and super.table are different. Anyway shadowing fields are not advised.
It is more complex than it sounds, but I think I am obliged to try something like it. I want to make an abstract parent class with a prototyping of an enum (I want to declare the enum with only one value probably that will be the default unitialized one and also declaring a couple of methods that I will be using from the subclass), then I want to class that will extend the abstract parent to actually intialize the very same enum (I know that this practically hides the parent enum) so that the kid class will define a set of items inside the enum, but keep the methods probably.
I do not know much about this level of abstraction so I will now describe the nature of my problem, in case there is a more practical solution:
I have a bunch of files that contain classes that implement a lot of commands based on enums. (e.g. class1 implements Observer has an update method that uses an enum-based switch to decide what command was picked, same applies for the other classes) I now want to abstract this whole thing in a way that I have an enum variable with the exact same name in all classes (e.g. CommandSet) so that I can have a generic method inside the parent that will be able to print a help list to my system using the inside methods of the enum. Now I know I can rewrite the exact same method in every class, but I want to abstract it so that others can keep on extending the library I am making!
Hopefully I am not too confusing or too confused and somone can help me! :)
Edit: Here is an idea of the code (Probably not right):
public abstract class Commands{
enum CommandSet{
// empty command, placeholder
null_command ("command name", "command description");
// the Strings used for name and description
private final String name;
private final String description;
// constructor
CommandSet(String name, String description){
this.name=name;
this.description=description;
}
// get parameters
public String getName(){
return name;
}
public String getDescription(){
return description;
}
}
public void showHelp(){
for (CommandSet i : CommandSet.values()) {
printf(i.getName(),":",i.getDescription());
}
}
}
public class StandardCommads extends Commands implements Observer{
// I want to change the enum here, just changing the values so that null_command ("command name", "command description") will get removed and I will add a dozen other values, but keep the methods that the parent had
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// I want the commands inside the switch cases defined inside this class's enum
switch(CommandSet.valueOf(String.valueOf(object)){
case command1: doStuff1();break;
case command2: doStuff2();break;
...
case commandN: doStuffN();break;
}
// other methods
void doStuff1(){
...
}
...
void doStuffN(){
...
}
}
public class NonStandardCommads extends Commands implements Observer{
// Another set of commands here for the enum keeping the same methods it had in the parent
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// Other set of commands inside this class used in the switch statement
switch(CommandSet.valueOf(String.valueOf(object)){
case Zcommand1: doStuffz1();break;
case Zcommand2: doStuffz2();break;
...
case ZcommandN: doStuffzN();break;
}
// other methods
void doStuffz1(){
...
}
...
void doStuffzN(){
...
}
}
Impossible: Java enums can neither extend another class nor be extended themselves.
They can however implement interfaces. Perhaps you can use that to your advantage.
There is something else about enums that may help you: enums are not immutable. You could change field values of the enums, however that would change them for the whole JVM.
Another approach maybe to pass your subclass instances into a method of the enum and have the enum use your subclass as a call back to get different functionality out of an enum for a different user of the enum.
Nope, you can't do that.
Java Enums run out of gas very quickly & definitely, when you want to add/extend more definitions or instantiate the enum instances, at a later time. (eg load them from database, configure them in an instance method, not just statically.)
Behaviour/ or logic in Java enums is kinda limited too -- you can define & set properties, but only what's statically initializable, and logic seems basic (you end up mainly just comparing references or ordinals, with the other defined enum constants).
What you can do:
You can implement an ancestor Command or AbstractCommand class, with a integer Code, and then subclass it to define concrete values/ additional codes/ load or configure instances, etc.
For further benefit, you get efficient switch & despatch (by Code) plus the ability to define further details/properties, instantiate commands as-needed, etc.
Essentially, this is how you used to define an Enum before Java supported them. Though you may be using them as value objects, rather than strictly static.
My expertise:
I've done extensive compiler & type-system work, tried enums for file-types and associated data/behaviour.. explored the outer limits, and reached the definite boundaries.
I also like being able to instantiate & return a new UnknownFileType("") as an answer, too. Enums can't do that.
Example:
(We'll despatch by String, not int -- since your code appears to be using Java 7. This makes command resolution easier, than requiring both a syntactical "name" and an internal integer "code".)
public static class Command {
protected String code;
protected String desc;
public String getCode() {return code;}
public String getDesc() {return desc;}
public Command (String code, String desc) {
this.code = code;
this.desc = desc;
}
public String toString() {return code;}
}
public class StandardCommands {
public static Command READ = new Command("READ", "read a record");
public static Command CREATE = new Command("WRITE", "create a record");
public static Command EDIT = new Command("WRITE", "modify a record");
}
public class FurtherCommands extends StandardCommands {
public static Command LIST = new Command("LIST", "list all records");
}
public class QueryCommands extends FurtherCommands {
public static class QueryCmd extends Command {
protected String search;
public String getSearch() {return search;}
// constructor..
}
public static QueryCmd QUERY_EXAMPLE = new QueryCmd("QUERY", "example", "query for specified string");
public static QueryCmd createQuery (String search) {
return new QueryCmd( "QUERY", search, "query for specified string");
}
}