Cannot reduce the visibility of the inherited method from object - java

I have defined the following two classes:
public abstract class Subject {
private ArrayList<ClockObserver> clockObserverList = new ArrayList<ClockObserver>();
public void attach(ClockObserver clockObserver) {
// begin-user-code
// TODO Auto-generated method stub
clockObserverList.add(clockObserver);
// end-user-code
}
public void dettach(ClockObserver clockObserver) {
// begin-user-code
// TODO Auto-generated method stub
clockObserverList.remove(clockObserver);
// end-user-code
}
protected void notify() {
// begin-user-code
// TODO Auto-generated method stub
for(int i= 0; i < clockObserverList.size(); i++)
{
clockObserverList.get(i).update();
}
// end-user-code
}
}
and
public class SystemClock extends Subject {
private int hour;
private int minute;
private int second;
public void setTime(int hour, int minute, int second) {
this.hour = hour;
this.minute= minute;
this.second = second;
notify();
}
public ClockTime getTime() {
ClockTime clockTime = new ClockTime();
clockTime.hour = this.hour;
clockTime.minute = this.minute;
clockTime.second = this.second;
return clockTime;
}
public void displayTime() {
System.out.println("Time is :" + this.hour + ":" + this.minute + ":" + this.second);
}
}
I got the following error for notify function:
Multiple markers at this line
- Cannot override the final method from Object
- overrides java.lang.Object.notify
- Cannot reduce the visibility of the inherited method from
Even when I change its visibility from protected to public, I still have the following error:
Multiple markers at this line
- Cannot override the final method from Object
Could you please help me what is the problem?

In Java, every class implicitly extends the Object class, which defines a method called notify. Therefore if you create a method notify in your class, the compiler will think that you tried to override the Object.notify method, which is obviously not the case.
Just rename your method notify and you should be alright.

final methods are such methods that cannot be overriden.
You cannot override public method making it protected.

The final modifier on a method means that the method cannot and must not be overridden. So you cannot override the method notify.
Regarding the visibility, you cannot "hide" methods you override, they would still be visible anyway simply by casting the variable to the super-class.
Imagine this:
class A {
protected String toString() { return "hidden"; } // Will not compile
}
A a = new A();
Object stillA = a; // a is an instance of A, so it is an instance of Object too
stillA.toString(); // This is still accessible, since Object.toString is public

No final method in java can be overridden by a subclass. In your case you are trying to override notify method of Object class which is not possible. If you really want to use the method of the class Object, then define a new method with some other name, write your code and then call notify within your new method.
For e.g.
public void notifySubject() {
for(int i= 0; i < clockObserverList.size(); i++) {
clockObserverList.get(i).update();
}
notify();
}

Related

Change and use variable by different methods

I've got a small question because oft a topic I didn't understand. There is one variable in a class. In the first method I want to give her a value. The second method have to change the value of this variable again. The new value of the variable is needed by a third method. I want to change and use this variable on every point of the class. Is this possible? I hope you know what I mean. Thanks for every help!
It is possible.
public class Test{
int counter;
public void initCounter(int initValue){
counter = initValue;
}
public void incCounter(){
counter++;
}
public void decCounter(){
counter--;
}
public void printCounter(){
System.out.println(counter);
}
}
If I understand you correctly, you need to send a variable into the methods so that they can modify it. As I understand, here it could be difficult becuause if you use wrapper types, they can't be modified. In such a case you can create a class that wraps your variable and can change it's values or you can use ready-to-go solutions from third party libraries.
For example, in apache-comons, they have a package:
org.apache.commons.lang3.mutable
That contains mutable wrappers for all primitive types(e.g. MutableInt).
Using your own wrapper or this classes you can modify variable inside methods and keep result saved without returning new values from these methods.
You can do , here an example :
public class PassingV {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public PassingV firsM(PassingV a){
a.setI(1);
return a;
}
public PassingV secondM(PassingV a){
a.setI(2);
return a;
}
public PassingV thirdM(PassingV a){
a.setI(3);
return a;
}
#Override
public String toString() {
return "PassingV [i=" + i + "]";
}
public static void main(String[] args) {
// TODO Auto-generated method stub
PassingV v = new PassingV();
System.out.println(v.firsM(v).toString());
System.out.println(v.secondM(v).toString());
System.out.println(v.thirdM(v).toString());
}
}
Result:
Becarful to the types of objects you are using and becarful at the methods (accessors for example ) you define ,or not define in the class .
They can totally change the way how your object has seen from the outside .
Lets modifiy our class a bit and lets see what happen .
Now instead of int i will use a String parameter.
public class PassingV {
private String i;
public String getI() {
return i;
}
public void setI(String i) {
this.i = i;
}
public PassingV firsM(PassingV a){
a.setI("HEY ");
//substring but it return the original value :D
System.out.println(a.getI().substring(2));
return a;
}
public PassingV secondM(PassingV a){
a.setI("JOE ");
return a;
}
public PassingV thirdM(PassingV a){
a.setI("LETS GO");
return a;
}
#Override
public String toString() {
return this.getI() ;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
PassingV v = new PassingV();
System.out.println(v.firsM(v).toString());
System.out.println(v.secondM(v).toString());
System.out.println(v.thirdM(v).toString());
}
}
Result:
As you can see with String object something changed , it happen because is
Immutable object
Following this link you can read more about Immutable Objects

Java. Implicit super constructor Settore() is undefined. must explicitly invoke another constructor

When I've Created the subclass Alieni from the Settore class I get the error "Implicit super constructor Settore() is undefined. must explicitly invoke another constructor", i've looked similar questions and the answer given was to put a default constructor in my Settore class, i've done it and still get the same error
public class Settore {
private Nome settoreNome;
private char letteraX;
private final int coordinataX;
private final int coordinataY;
private int giocatoriPresenti;
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public int getGiocatoriPresenti() {
return giocatoriPresenti;
}
public void setGiocatoriPresenti(int giocatoriPresenti) {
this.giocatoriPresenti = giocatoriPresenti;
}
public char getLetteraX() {
return letteraX;
}
public void setLetteraX(char letteraX){
this.letteraX = letteraX;
}
public Settore (){}//suggestion given, still doesn't fix the problem, it just makes it worse
public Settore (int coordinataX, int coordinataY){
char myChar =letteraX;
int i=(int)myChar;
this.coordinataX=i-97;
this.coordinataY=coordinataY-1;
}
public int getX(){
return coordinataX;
}
public int getY(){
return coordinataY;
}
public Nome getSettoreNome() {
return settoreNome;
}
public void setSettoreNome(Nome settoreNome) {
this.settoreNome = settoreNome;
}
}
public enum Nome {
SICURO, PERICOLOSO, SCIALUPPA, ALIENI, UMANI
}
public class Alieni extends Settore {
public Alieni() {//this is where i get the error Implicit super constructor Settore() is undefined. must explicitly invoke another constructor
setSettoreNome(Nome.ALIENI);
}
}
It shows error even when you add a default constructor, bcoz the final variables you declared should have some value.They should be assigned values in the default constructor as below:
public Settore (){
coordinataX=5;
coordinataY=22;
}
Another way, if you want to use the parameterized constructor you have declared:
public Alieni()
{
super(5,6); //call to super class constructor
setSettoreNome(Nome.ALIENI);
}
You needed to add a default constructor because you need to initialize coordinataX and coordinataY:
public Settore(){
coordinataX=1;
coordinataY=2;
}
Otherwise the compiler will complain that these may not be initialized because a final member variable needs to be initialized at the declaration or in the constructor.

Calling an overridden superclass method from a subclass

public class F {
protected int a=0, b=0;
public F() {
a = 2;
b = 2;
}
public void increase() {
upA();
}
public void upA() {
a = a + 1;
}
public String toString() {
return a+" "+b;
}
}
public class G extends F {
public void increase() {
super.increase();
upB();
}
public void upA() {
a = a + a;
}
public void upB() {
b = b + 1;
}
}
What is printed in the Output window by the following Java fragment?
G g = new G();
g.increase();
System.out.println(g);
Can someone explain to me why the answer is 4,3
(ie. the subclass method is called even though I have called super.increase() which calls the upA method in the superclass?)
All your methods are being called virtually, with overrides applying. So this code in F:
public void increase() {
upA();
}
... is invoking G.upA(), because the object it's calling upA() on is an instance of G.
So the execution flow for increase() is:
G.increase() calls super.increase()
F.increase() calls upA()
G.upA() executes (so a = 4)
G.increase() calls upB()
G.upB() executes (so b = 3)
Think of increase() as being implemented like this
public void increase() {
this.upA();
}
and then ask yourself what object "this" is.
You are seeing "polymorphic" behaviour, and it's a really powerful feature of Object languages.
Note that you can write
F gInDisguiseAsAnF = new G();
gInDisguiseAsAnF.increase();
and still get the same result. Which version of the upA() method is selected on the basis of the type that was newed.
public void increase() {
upA();
}
is same as this.upA(), so the method in G was called, since this is instance of G.
calling super won't restrict your current instance only in super type.
This is being called from increase() of F
public void upA() {
a = a + a; // a=2+2
}
Not,
public void upA() {
a = a + 1; //not a=2+1
}

how to print object value with String method

I have an abstract class like this
public abstract class Temperature
{
private float value;
public Temperature(float v)
{
value = v;
}
public final float getValue()
{
return value;
}
public abstract Temperature toCelsius();
public abstract Temperature toFahrenheit();
public abstract Temperature toKelvin();
}
then I have classes that extend this Temperature class, example:
public class Celsius extends Temperature
{
public Celsius(float t)
{
super(t);
}
public String toString()
{
return "";
}
#Override
public Temperature toCelsius() {
// TODO Auto-generated method stub
return this;
}
public Temperature toKelvin(){
return new Kelvin(this.getValue() + 273);
}
#Override
public Temperature toFahrenheit() {
// TODO Auto-generated method stub
return new Fahrenheit(this.getValue() * 9 / 5 +32);
}
}
main method creates objects of of Celcius
Temperature inputTemp = null, outputTemp = null;
inputTemp = new Celsius(temp_val);
outputTemp = inputTemp.toCelsius();
then prints the object by calling this method
System.out.println("\n The converted temperature is " + outputTemp.toString() +"\n\n");
}
What do i have to put in the toString method in order to print the desired value? this.super.getValue() didnt work and im kinda clueless. Since we are not going to be returning the same object everytime, dont we have to use the superclass?
It will be enough if you use:
public String toString()
{
return Float.toString(this.getValue());
}
this.super is invalid syntax. super is not a field of this. It's a keyword that allows calling the superclass implementation of a method rather than calling the overridden implementation, from the current class. You just need
return Float.toString(this.getValue());
or
return Float.toString(getValue());
or even
return Float.toString(super.getValue());
But using super.getValue() is useless, since the subclass doesn't override the base getValue() method, and you thus don't need to explicitely use the super implementation of the method.

polymorphic call depends on variable

I have the following problem. Am trying to make a polymorphic call and the result would depend on the variable that changes value depending on the underlying class. Tried different things however it doesn't work. Please let me know what should be changed. Problem is that although c.w reads both the local variable w, which is defaulted to 0 and reads the one from appropriate class it always defaults to 0. Here is the code:
class Cycle{
private int w = 0;
public void move(){
System.out.println("Cycle moving");
}
public int wheels(Cycle c){
switch (c.w){
case 1: return 1;
case 2: return 2;
case 3: return 3;
default: return 0;
}
}
}
class Unicycle extends Cycle{
public int w = 1;
public void go(){
System.out.println("Unicycle go");
}
}
class Bicycle extends Cycle{
public int w = 2;
public void go(){
System.out.println("Bicycle go");
}
}
class Tricycle extends Cycle{
public int w = 3;
public void go(){
System.out.println("Tricycle go");
}
}
public class TestCycle {
public static void ride(Cycle c){
c.move();
int now = c.wheels(c);
System.out.println(now);
}
public static void main(String[] args){
Bicycle b = new Bicycle();
ride(b);
Unicycle u = new Unicycle();
ride(u);
Tricycle t = new Tricycle();
ride(t);
}
}
Your problem (well one of them) is that you are redefining the class variable 'w' in each of your subclasses. Define it one as a member of 'Cycle' and have each subclass set it correctly in their constructors.
class Cycle{
protected int w;
public void move(){
System.out.println("Cycle moving");
}
public int wheels(){
return w;
}
}
class Unicycle extends Cycle{
public Unicycle() {
w = 1;
}
public void go(){
System.out.println("Unicycle go");
}
}
Or you can define an abstract method called 'wheels()' in the superclass and override it in the subclasses. It's a matter of taste.
the wheels method should be more like
public int getWheelCount(){
return this.w;
}
You invoke it on the instance itself, you don't need to pass an argument. If the current instance is a Tricycle, the method will return 3, etc...
Since Cycle.w is private, it's not visible from its inheritors. This means that for example Tricycle.w it's not the "same" variable, and it's not visible in Cycle (that's why you always get 0). You have to make Cycle.w at least protected, then remove w from all subclasses, and set its value in each subclass's constructor to what you want.
It's probably not the answer you are looking for, but the following works. Please give more details on what you are trying to do.
public abstract class Cycle {
protected int nWheels;
protected String goText;
// no constructor.
public void go() {
System.out.println(goText);
}
public int wheels() {
return nWheels;
}
}
...
public class Unicycle extends Cycle {
public Unicycle() {
nWheels = 1;
goText = "Unicycle go";
}
}
Note that I made Cycle abstract because I don't want it to ever be instantiated.
EDIT:
public static int getNumberOfWheels(Cycle cycle) {
return cycle.wheels();
}
which is obviously not very useful since a simple call to cycle.wheels() would do the same as calling this function.
I'm not sure why you want to avoid constructors. Maybe you should write the exact question you are trying to answer.

Categories

Resources