#About overriding

1 messages · Page 1 of 1 (latest)

chilly mango
#

So our teacher gave us this syntax :
class Price{
void price(){

}

}

class Car extends Price{
void price(){

}

}
class Bike extends Price{
void price(){

}

}
class Laptop extends Price{
void price(){

}

}

and the question was why did we do this overridng, isnt the point of it to reduce writing code again and again?Couldn't we have just made the function for each class seperately instead of making 1 parent class and having multiples child classes of it?

hushed onyxBOT
#

<@&987246399047479336> please have a look, thanks.

#

Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#
TJ-Bot
So our teacher gave us this syntax : class Price{ void price(){ } } class Car extends Price{ void price(){ } } class Bike extends Price{ void price(){ } } class Laptop extends Price{ void price(){

rice(){

}

}

When a subclass has a method with the same name and signature as a method in its superclass, it is said to override that method. In this example, the price method in the Car and Bike classes overrides the price method in the Price class.

When an object of type Car or Bike calls the price method, it will execute the overridden method in the subclass instead of the one in the superclass. This allows for polymorphic behavior, where different subclasses can have their own implementation of a common method.

It is important to note that when overriding a method, the subclass must have the same return type and parameter list as the superclass method. The access modifier (public, private, protected) can be more permissive but not more restrictive than that of the superclass method.

Additionally, methods marked as final or static cannot be overridden. Final methods cannot be changed by subclasses, and static methods belong to the class itself rather than individual objects.

Overall, method overriding in Java allows for flexibility and customization in how subclasses inherit behavior from their superclasses.

cosmic gorge
#

and very contrived

#

id suggest u read this to understand some of the reasoning

hushed onyxBOT
#

An abstract class denotes a yet unfinished class. For example, it might be only done to 70% but there are still 30% missing. As such, it is used to create a template for other classes that extend it. The extending class can then concentrate on only doing the remaining 30% since 70% are already done. This can greatly reduce code duplication.

In general, a class is abstract if it has an abstract method. An abstract method is a method that is missing any implementation:

abstract class Animal {
  String name;

  Animal(String name) {
    this.name = name;
  }

  String getName() { // regular method
    return name;
  }

  abstract void makeNoise(); // No method body
}

Since the class is not finished yet and makeNoise is lacking any implementation, it is impossible to create instances of it in that state:

Animal animal = new Animal("Buddy"); // Does not compile! Can not instantiate abstract class

However, we can use it as template for extending it and get the existing name-functionality for free (getName()). But then we are required to implement everything that is still abstract, i.e. incomplete like makeNoise:

class Dog extends Animal {
  Dog() {
    super("Buddy"); // all dogs are called Buddy
  }

  @Override
  void makeNoise() {
    System.out.println("Wuff Wuff");
  }
}

And now we can create instances of it and use the methods:

Dog dog = new Dog();
System.out.println(dog.getName()); // Prints Buddy
dog.makeNoise(); // Prints Wuff Wuff
chilly mango
cosmic gorge
#

its not a perfect fit to ur situation but its the primary example from practice that motivates inheritance and by that any need or use of override

chilly mango
#

I get the need for override but why cant we just make different methods for different classess eperately?

cosmic gorge
#

ah. then u need to read this:

hushed onyxBOT
#

An interface defines a set of method signatures, as contract. It can greatly increase code modularity. Often, interfaces are property-driven.

interface CanWalk {
  void walkLeft();
  void walkRight();
}

There is no method body. So if a class implements CanWalk, he makes the promise to offer those methods:

class Player implements CanWalk {
  int x;

  @Override
  void walkLeft() {
    x--;
  }

  @Override
  void walkRight() {
    x++;
  }
}

Someone could now demand a CanWalk instance and use the methods:

class Mover {
  static void moveAround(CanWalk canWalk) {
    for (int i = 0; i < 10; i++) {
      canWalk.walkRight();
    }
    canWalk.walkLeft();
    canWalk.walkRight();
  }
}

Note that the moveAround accepts everything that can walk.

Mover.moveAround(player);

We could also give it a Dog, as long as it implements CanWalk.

You have two options to create instances of interfaces:

  1. Create a class that implements the interface, like Player
  2. Use an anonymous class:
CanWalk canWalk = new CanWalk() {
  @Override
  void walkLeft() {
    System.out.println("Walking left");
  }

  @Override
  void walkRight() {
    System.out.println("Walking right");
  }
};

An interface that only offers one method is called a functional interface:

@FunctionalInterface
interface IntOperation {
  int operate(int a, int b);
}

You have two additional options to create instances of it:
3. Lambda expression

IntOperation operation = (a, b) -> a * b;
System.out.println(operation.operate(5, 3)); // Prints 15
  1. Method reference
// Method in MathUtil
static int multiply(int a, int b) {
  return a * b;
}

// Use it as
IntOperation operation = MathUtil::multiply;
System.out.println(operation.operate(5, 3)); // Prints 15
cosmic gorge
#

in particular the first half

#

so by having a common type that defines a method (in ur case Price), we can write code that deals with anything that is Price

#

instead of writing one method that takes Car, another that takes Laptop, one for Bike,...

#

we can write just one working with Price and call it a day

chilly mango
#

makes sens

#

ill have to practice some more to get the hang of it.

cosmic gorge
#

but yeah. the way ur teacher wrote it isnt meaningful

#

u would either go for an interface (method has no body) or for an abstract class (if u have a meaningful default behavior)

#

so in this case Price should be an interface instead and prob also be renamed to HasPrice

#

the core principle remains the same though. so with ur code someone could write for example

#
List<Price> store = new ArrayList<>();

...
store.add(new Bike());
store.add(new Laptop());
...

int cost = store.stream()
  .mapToInt(Price::price)
  .sum();

System.out.println("All items in the store cost together: " + cost);
#

or sth in that direction

#

which u couldn't do without Price. since otherwise u cant put Laptop and Bike into the same list without going down to their first common type, which would then be List<Object>. and since Object has no price method u couldnt call it then