If we have for example :
class Person {
// public void printInfos(){ }
}
class Student extends Person {
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher extends Person(){
public void printInfos(){
System.out.println("teacherInfos");
}
}
main:
Person p1 = new Student();
Person p2 = new Teacher();
I want to write : p1.printInfos() and p2.printInfos() and print "studentInfos" & "teacherInfos" but I can't find a solution other than declaring an empty method inside the class Person (since we can't declare it as abstract and override it otherwise there will be no instanciation possible).
I feel that the declaration of an empty method is wrong even if it works.
You should exactly declare Person as interface. Logically, Person shouldn't be instantiated. Defining new class and empty-bodied method are superfluous in this case.
If you insist on the gobbledygook approach, there is no sane way to do that other than defining new class.
interface Person {
public void printInfos();
}
class Student implements Person {
#Override
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher implements Person {
#Override
public void printInfos(){
System.out.println("teacherInfos");
}
}
main:
Person p1 = new Student();
Person p2 = new Teacher();
Please tell me more about your needs for this class. Is there any good reason why you would want to create Person instance?
If not it is clearly an abstract class for me and I think you should make it abstract.
You will still have option to declare constructor, some method that are "default" for the subclasses (an provide them an implementation) and make printInfos an abstract method.
abstract class Person {
abstract void printInfos();
}
class Student extends Person {
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher extends Person{
public void printInfos(){
System.out.println("teacherInfos");
}
}
Related
Here is my base class:
#Service
public class BasicUserManagerService implements UserManager {
#Autowired
private UserRepository UserRepository;
private Logger logger = LoggerFactory.getLogger(UserManagerPasswordController.class);
#Override
public void createUser(User User) {
if (UserRepository.findByEmail(User.getEmail()) != null)
throw new InvalidDataException("User already registered with this email address");
UserRepository.save(User);
logger.info("Created user: {}", User.getEmail());
}
}
I am trying to extend this class as follows:
#Service
public class UserManagerService extends BasicUserManagerService implements UserManager {
#Override
public void createUser(User User) {
super().createUser(User);
}
}
But I keep getting the error that the call to super() must be the first statement in the constructor body.
As you can see I don't have a constructor and even when I add it, I get the same error. Why is this happening and how can I avoid it?
Change this super usage. super() is parent's constructor. super is a reference to the parent class.
#Service
public class UserManagerService extends BasicUserManagerService implements UserManager {
#Override
public void createUser(ProxyCircuitUser proxyCircuitUser) {
super.createUser(proxyCircuitUser);
}
}
super() is a call to the parent class constructor;
which is not at all what you want.
Instead, you want to call the parent class implementation of the createUser method.
The code for that is: super.createUser(user)
Here are various uses of Super Keyword in Java:
Use of super with variables
This scenario occurs when a derived class and base class has same data members. In that case there is a possibility of ambiguity for the JVM.
/* Base class vehicle */
class Vehicle
{
int maxSpeed = 120;
}
/* sub class Car extending vehicle */
class Car extends Vehicle
{
int maxSpeed = 180;
void display()
{
/* print maxSpeed of base class (vehicle) */
System.out.println("Maximum Speed: " + super.maxSpeed);
}
}
/* Driver program to test */
class Test
{
public static void main(String[] args)
{
Car small = new Car();
small.display();
}
}
Output:
Maximum Speed: 120
Use of super with methods
This is used when we want to call parent class method. So whenever a parent and child class have same named methods then to resolve ambiguity we use super keyword.
/* Base class Person */
class Person
{
void message()
{
System.out.println("This is person class");
}
}
/* Subclass Student */
class Student extends Person
{
void message()
{
System.out.println("This is student class");
}
// Note that display() is only in Student class
void display()
{
// will invoke or call current class message() method
message();
// will invoke or call parent class message() method
super.message();
}
}
/* Driver program to test */
class Test
{
public static void main(String args[])
{
Student s = new Student();
// calling display() of Student
s.display();
}
}
Output:
This is student class
This is person class
Use of super with constructors
super keyword can also be used to access the parent class constructor. One more important thing is that, ‘’super’ can call both parametric as well as non parametric constructors depending upon the situation.
/* superclass Person */
class Person
{
Person()
{
System.out.println("Person class Constructor");
}
}
/* subclass Student extending the Person class */
class Student extends Person
{
Student()
{
// invoke or call parent class constructor
super();
System.out.println("Student class Constructor");
}
}
/* Driver program to test*/
class Test
{
public static void main(String[] args)
{
Student s = new Student();
}
}
Output:
Person class Constructor
Student class Constructor
As super() will call the constructor of parent class, it should be the first statement to be executed in child class's constructor. If you want to call a method of parent class use super instead of super().
For More Info please read: super in java
I'm learning abstract classes vs interfaces at the moment and trying to figure out situations where to use one over the other. I'm having trouble figuring out this example at the moment:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("over here");
}
}
public class Thing extends Tract implements Face {
public void test() {
// what should print out?
}
}
Here, the test() function is implemented in the abstract class. If you don't implement it in the subclass, would it call the abstract class' method and print out "over here"? Does the interface accept implementations from an ancestor class or do you have to implement it in the subclass, therefore overriding the abstract class implementation?
All the interface cares about is that the class has implemented a method called test() that returns void. It does not matter whether the method is implemented in the class directly or in any ancestor (parent) class.
In your case, the Thing class has inherited its definition of test() from Tract, and therefore implements the Face interface without you having to provide a definition explicitly.
In the class "Tract" you have given an implementation for the method coming from the interface. Also you override it in "Thing" class so when calling this method on a Thing instance then this version(Thing version) is going to be called.
All java methods are virtual.
lets consider little bit modified code,
I hope, you will get the idea:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("Tract here");
}
}
public class Thing extends Tract implements Face {
public void test() {
System.out.println("Thing here");
}
}
public class Thing2 extends Tract implements Face {
}
lets go to output:
Tract tr = new Tract();
tr.test();
will not compile because you can't instantiate abstract class.
Thing th = new Thing();
th.test();
will print "Thing here"
Thing2 th2 = new Thing2();
th2.test();
will print "Tract here",
because you not overwritten the test() method in abstract class.
Main idea of this approach - you can abstract implementation in the future use
class C {
void print(Face face) {
face.test();
}
}
new C(new Thing()).print();
will print "Thing here";
new C(new Thing2()).print();
will print "Tract here";
You can hide different implementations
But this is not main idea of abstract classes.
main idea abstract classes are:
public interface Face {
public void test();
}
public abstract class Abstract {
abstract public void test();
}
public class Thing1 extends Abstract implements Face {
public void test() {
System.out.println("Thing1 here");
}
}
public class Thing2 extends Abstract implements Face {
public void test() {
System.out.println("Thing2 here");
}
}
main idea - you can declare method without implementation
new C(new Thing1()).print();
will print "Thing1 here";
new C(new Thing2()).print();
will print "Thing2 here";
main idea - you declare the method in abstract class, that you MUST override to compile code.
I hope, this is enough explained answer.
I am doing an exercise, the book is not helping me grasp the concept, neither are the online resources. This may seem really silly but I don't know what I'm missing!!! I am quite new to Java and have had a look at other examples on stack but to no avail :s I need to declare 3 interfaces. Each interface needs to declare a method with the same name as its interface. Then the abstract class is extended by 3 classes which implement the aforementioned interfaces.Each class needs to be instantiated. If anyone could explain the procedure to this I would be eternally grateful.
interface antiLockBrakes{
public void antiLockBrakes();
}
interface cruiseControl{
public void cruiseControl();
}
interface powerSteering{
public void powerSteering();
}
public abstract class Auto{
abstract class Model1 extends Auto implements antiLockBrakes{
public abstract void antiLockBrakes();
Model1 mod1 = new Model1();
mod1.antiLockBrakes();
}
public static void main(String[] args){
}
}
this is your question: someone to explain how exactly to declare and interface and then have it implemented in the abstract class right??
Here's the answer for it.
See lets consider I have an interface
interface someInterface{
public void someMethod();
}
Now to implement the someInterface in abstract class
public abstract class SomeClass implements someInterface{
public void someMethod(){
System.out.println("Inside someMethod");
}
public abstract myMethod();
}
See in the class SomeClass we have implemented interface by giving definition to method someMethod() and since we want this SomeClass to be a abstract class we have defined one abstract method myMethod() for it.
Now any class which extends from SomeClass will also implement interface someInterface implicitly (because SomeClass has implemented it) and if it want its own definition for someMethod() it can override it. But if a child class wants to be a concrete class ( a class in which all its method will have implementation) then it has to provide implementation for abstract method myMethod().
HTH:)
this is what I like to use to see the difference between abstract classes and interface classes
interface class
//I say all motor vehicles should look like that :
interface MotorVehicle {
void run();
int getFuel();
}
// my team mate complies and write vehicle looking that way
class Car implements MotorVehicle {
int fuel;
public void run() {
System.out.println("Wrroooooooom");
}
public int getFuel() {
return this.fuel;
}
}
abstract class
// I say all motor vehicles should look like that :
abstract class MotorVehicle2 {
int fuel;
// they ALL have fuel, so why let others implement that ?
// let's make it for everybody
int getFuel() {
return this.fuel;
}
// that can be very different, force them to provide their
// implementation
abstract void run();
}
// my team mate complies and write vehicle looking that way
class Car2 extends MotorVehicle2 {
void run() {
System.out.println("Wrroooooooom");
}
}
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}
In the following code:
import java.io.*;
public class MyClass1
{
MyClass1()
{
System.out.println("base class");
}
public void print()
{
System.out.println("base print");
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
System.out.println("child class");
}
public void print()
{
System.out.println("child print");
}
}
Why is it that when I create an instance of type ChildClass the constructor of the base class is also executed??
Because your child class extends the base class - it's an instance of the base class and has all of the same fields and variables, etc. Thus the base class must also be instantiated.
For a concrete example, imagine your base class had the following in:
public class Base
{
final private int id;
public Base()
{
this(-1);
}
public Base(int id)
{
this.id = id;
}
public getId()
{
return id;
}
}
A final variable is guaranteed to be instantiated when the class is constructed. Your child class will have an id field (even if it cannot access it directly with child methods), and since this field is private you cannot possible instantiate it with the child constructor - so a base class constructor must be called.
Bear in mind that this isn't solely an issue with final variables, nor is it unique to any particular features you may use - since your child class is a base class, it needs to be properly instantiated as one.
Because that's what's supposed to happen :-)
Your derived class uses the base class as a foundation. In OO speak it is-a base class. That base class also needs to initialise itself, and consequently its constructor must be called.
It's not obvious from your example, but it will make more sense if you give your base class some (protected) members. Initialise them in the base constructor, and consequently they will have the expected values when viewed from your derived class upon construction.
See below. The field value is visible in the child class. What would you expect as the initialised value ?
public class MyClass1
{
protected int value;
MyClass1()
{
System.out.println("base class");
this.value = 42;
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
// what would you expect 'value' to be here ?
System.out.println("child class " + value);
}
}
Because compiler by default add super() constructor in the child class constructor if it is not specified . Every Constructor Should have either this() in case of without inheritance or super() method when ever there is an inheritance . To illustrate it i have taken this example .
public class Vehicle {
protected int wheels;
protected int lights;
Vehicle(){
System.out.println("Vehicle Class Constructor");
this.wheels=4;
this.lights=2;
}
}
Vehicle is the parent class
class Car extends Vehicle {
public Car(){
#Compiler add the super() constructor by default
System.out.println("Car class constructor");
}
}
Car is the Child class
public class TestCar {
public static void main(String args[]){
Car c = new Car();
System.out.println("Wheels" + c.wheels);
System.out.println("Lights" + c.lights);
}
}
In above code snippet When i compile the TestCar.java file during the Compile time the compiler looks for the Car constructor and checks whether Car class has any parent as soon as it checks that Car class extends the parent class Vehicle , it checks whether user had provided super() in inheritance tree . if not it adds one .
Hope this helps !