Calling non-abstract method from subclass - java

Suggested to pass a File class object to playClip() that references the animal sound file and catches any exceptions outputting "Meow" if any exceptions were caught. When I run Main function I hear the cat sound in the speakers.
Have I passed the File object reference to playClip() the right way?
public void makeSound() {
try {
playClip(new File("Cat.wav"));
} catch (Exception e) {
System.out.println("Meow");
}
}
With the following main function
public class Main {
public static void main(String[] args) {
Cat sound = new Cat();
sound.makeSound();
}
}

In your abstract class, create the method playClip:
public abstract class Sound {
abstract public void makeSound();
public void playClip(File clipFile) {
// code plays a file and has some exception handling
}
}
public class Cat extends Sound {
public Cat() {
super();
}
#Override
public void makeSound() {
playClip(new File("/sound_file"));
}
}
Of course, playClip() could also be abstract. It depends what you want.

Related

Overriding an anonymous class's methods in Java

In below example (in the commented block) I'm trying to override jump() method of an anonymous class, however getting compilation error. Can someone help me understand what's wrong here?
class Animal {
public void bark() {
System.out.println("Inside bark");
}
public void jump() {
System.out.println("Inside jump");
}
}
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
}; /* {
public void jump() {
System.out.println("Subclass jump");
}
};*/
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}
Edit:
Here's the compilation error I'm getting in IDE - ';' expected.
And from the comments, it seems some folks are not getting my question. With the above example, I wanted to understand whether we can override an anonymous class's methods or not?.
Again, the main motive is to see (and understand) why Java compiler allowed to create an anonymous class by starting a {} block followed by new Animal(), and didn't allow the same behaviour further (chaining of {} blocks to allow creation of further subclasses)
Don't end and restart the block, override both methods in one block, same as you would in a regular subclass:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
animal.bark(); // Subclass bark
animal.jump(); // Subclass jump
}
}
UPDATE
Updates to the question says you're trying to subclass an anonymous class, e.g. you're trying to do this:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal barkingAnimal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
Animal jumpingAnimal = <subclass barkingAnimal> { // Can't be done
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
You can't do that, because the unnamed anonymous class cannot be identified as the base class. You can however do it using local classes, which are like named anonymous classes, as contradictory as that sounds:
class AnonymousClassExample001 {
public static void main(String[] args) {
class BarkingAnimal extends Animal {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
class JumpingAnimal extends BarkingAnimal {
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
Animal barkingAnimal = new BarkingAnimal();
Animal jumpingAnimal = new JumpingAnimal();
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
Alternatively, jumpingAnimal could also be done using anonymous class syntax, instead of local class syntax.
I think it should be like this
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
public void jump() {
System.out.println("Subclass jump");
}
};
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}

How to force derived class to call super class method at multiple layers?

I am trying to find the most elegant way to allow a child and parent to react to an event initiated by the grandparent. Here's a naive solution to this:
abstract class A {
final public void foo() {
// Some stuff here
onFoo();
}
protected abstract void onFoo();
}
abstract class B extends A {
#Override
final protected void onFoo() {
// More stuff here
onOnFoo();
}
protected abstract void onOnFoo();
}
class C extends B {
#Override
protected void onOnFoo() {
// Even more stuff here
}
}
So basically, I'm trying to find the best way to allow all related classes to perform some logic when foo() is called. For stability and simplicity purposes I prefer if it is all done in order, although it's not a requirement.
One other solution I found involves storing all the event handlers as some form of Runnable:
abstract class A {
private ArrayList<Runnable> fooHandlers = new ArrayList<>();
final public void foo() {
// Some stuff here
for(Runnable handler : fooHandlers) handler.run();
}
final protected void addFooHandler(Runnable handler) {
fooHandlers.add(handler);
}
}
abstract class B extends A {
public B() {
addFooHandler(this::onFoo);
}
private void onFoo() {
// Stuff
}
}
class C extends B {
public C() {
addFooHandler(this::onFoo);
}
private void onFoo() {
// More stuff
}
}
This method is certainly preferable to the first. However I am still curious if there is a better option.
Have you considered the Template Method pattern? It works well to define a high level method that delegates to derived types to fill-in the gaps.
What about this by calling the super method?
class A {
void foo() {
System.out.println("Some stuff here");
}
}
class B extends A {
#Override
void foo() {
super.foo();
System.out.println("More stuff here");
}
}
class C extends B {
#Override
void foo() {
super.foo();
System.out.println("Even more stuff here");
}
}

How to pass Object Context to a callback interface in Java

Trying to get a handle on "callback interface". The concept as I understand it make sense except for the following
//FromSomeClass1
MyInterface conect;
public void setInterface(MyInterface myInter)
{
this.conect=myInter;
}
interface MyInterface
{
public void update(String str);
}
(Fuzziness starts here)
So when another class attempts to
//FromSomeClass2 implements MyInterface
...onCreate()
{
SomeClass1 newC = new SomeClass1()
newC.setInterface(this) ;
}
update(String str){
....code
}
this will not work because I am passing to a new object ? Unless I make the "conect" variable in Class1 static (Good Idea bad Idea...consequences ???)
Simply what is the correct way to pass the object back to "setInterface" method .
Hope that made sense and Thank You.
p.s.
To all those who want a good understanding of call backs this link will help.
Consider an example Animal interface with a single says(String) callback,
interface Animal {
public void says(String msg);
}
Next, let's add a class that uses the Animal interface to say something -
class Say {
public void say(Animal animal) {
animal.says("Bawk");
}
}
Now let's implement two different Animal(s) - we're going to have a Cow class and a Sheep class,
class Cow implements Animal {
public void says(String msg) {
System.out.printf("%s, I mean moo!%n", msg);
}
}
class Sheep implements Animal {
public void says(String msg) {
System.out.printf("%s, I mean baah!%n", msg);
}
}
Finally, to demonstrate the callback method we defined above -
public static void main(String[] args) {
Say say = new Say();
say.say(new Cow());
say.say(new Sheep());
}
Output is
Bawk, I mean moo!
Bawk, I mean baah!
Is not that you need to make it static. I mean, you could make everything in SomeClass1 and make the client register by calling an static method SomeClass1.setInterface(this)
I won't recommend doing that tough. This is an example fallowing your code:
import java.util.HashSet;
import java.util.Set;
public class CallbackExample {
interface MyInterface {
public void update(String str);
}
static class SomeClass1 {
private Set<MyInterface> connects = new HashSet<MyInterface>();
public void register(MyInterface myInter) {
this.connects.add(myInter);
}
public void doWork(String someParam) {
for (MyInterface myInterface : connects) {
myInterface.update(someParam);
}
}
}
static class SomeClass2 implements MyInterface {
public void onCreate(SomeClass1 caller) {
caller.register(this);
}
#Override
public void update(String str) {
System.out.println("Doing some logic in update for " + str);
}
}
public static void main(String[] args) {
// Caller and callback creation are decoupled
SomeClass1 caller = new SomeClass1();
SomeClass2 callback = new SomeClass2();
// alternative 1. Preferred
caller.register(callback);
// alternative 2. Fallowing your example
callback.onCreate(caller);
caller.doWork("param1");
}
}
A good example of the use of callbacks is the android-async-http library. To make a HTTP request, you call a method and pass in the details of the request along with an object that implements a certain callback interface. The request method returns immediately, but after the request is complete, the library's worker thread sets up a call in the main thread to a method on the callback object you provided.

Class is not Abstract and does not Override error in Java

I am getting a compile time error with Java:
MyClass is not abstract and does not override abstract method
onClassicControllerRemovedEvent(
wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent)
in wiiusejevents.utils.WiimoteListener)
Here is the class:
import wiiusej.WiiUseApiManager;
import wiiusej.Wiimote;
import wiiusej.wiiusejevents.physicalevents.ExpansionEvent;
import wiiusej.wiiusejevents.physicalevents.IREvent;
import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent;
import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent;
import wiiusej.wiiusejevents.utils.WiimoteListener;
import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent;
public class MyClass implements WiimoteListener{
public void onButtonsEvent(WiimoteButtonsEvent arg0) {
System.out.println(arg0);
if (arg0.isButtonAPressed()){
WiiUseApiManager.shutdown();
}
}
public void onIrEvent(IREvent arg0) {
System.out.println(arg0);
}
public void onMotionSensingEvent(MotionSensingEvent arg0) {
System.out.println(arg0);
}
public void onExpansionEvent(ExpansionEvent arg0) {
System.out.println(arg0);
}
public void onStatusEvent(StatusEvent arg0) {
System.out.println(arg0);
}
public void onDisconnectionEvent(DisconnectionEvent arg0) {
System.out.println(arg0);
}
public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) {
System.out.println(arg0);
}
public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) {
System.out.println(arg0);
}
public static void main(String[] args) {
Wiimote[] wiimotes = WiiUseApiManager.getWiimotes(1, true);
Wiimote wiimote = wiimotes[0];
wiimote.activateIRTRacking();
wiimote.activateMotionSensing();
wiimote.addWiiMoteEventListeners(new MyClass());
}
}
Can I get a better explanation of what this error means?
How to reproduce that error as simply as possible:
Java code:
package javaapplication3;
public class JavaApplication3 {
public static void main(String[] args) {
}
}
class Cat implements Animal{
}
interface Animal{
abstract boolean roar();
}
Shows this compile time error:
Cat is not abstract and does not override abstract method roar() in Animal
Why won't it compile?
Because:
You created a class Cat which implements an interface Animal.
Your interface called Animal has an abstract method called roar which must be overridden.
You didn't provide for method roar. There are many ways to eliminate the compile time error.
Remedy 1, have Cat override the abstract method roar()
package javaapplication3;
public class JavaApplication3 {
public static void main(String[] args) {
Cat c = new Cat();
System.out.println(c.roar());
}
}
class Cat implements Animal{
public boolean roar(){
return true;
}
}
interface Animal{
abstract boolean roar();
}
Remedy 2, change Cat to be an abstract like this:
package javaapplication3;
public class JavaApplication3 {
public static void main(String[] args) {
Cat c;
}
}
abstract class Cat implements Animal{
}
interface Animal{
abstract boolean roar();
}
Which means you can't instantiate Cat anymore.
Remedy 3, have cat stop implementing Animal
package javaapplication3;
public class JavaApplication3 {
public static void main(String[] args) {
Cat c = new Cat();
}
}
class Cat{
}
interface Animal{
abstract boolean roar();
}
Which makes roar() no longer a contract for things that animals must know how to do.
Remedy 3, extend a class rather than implementing an interface
package javaapplication3;
public class JavaApplication3 {
public static void main(String[] args) {
Cat c = new Cat();
System.out.println(c.roar());
}
}
class Cat extends Animal{
}
class Animal{
boolean roar(){
return true;
}
}
The remedy to use depends on what the best model is to represent the problem being represented. The error is there to urge you stop "programming by brownian motion".
Your class implements an interface WiimoteListener, which has a method onClassicControllerRemovedEvent. However, the methods in interfaces are abstract, which means they are essentially just contracts with no implementations. You need to do one of the things here:
Implement this method and all the other methods that this interface declares, which make your class concrete, or
Declare your class abstract, so it cannot be used to instantiate instances, only used as a superclass.
When you implement an Interface you must implement all the methods in that interface. You didn't implement onClassicControllerRemovedEvent.
It appears that WiimoteListener is an interface which defines an onClassicControllerRemovedEvent method. Your class must define all methods that an interface declares or it will not compile without errors.
It may also be that this class was designed using a different version of the WiimoteListener interface (based on an older or newer version of the jar that includes that interface) and that version did not declare the above mentioned method. If so, it may just require building against the version of the jar that your class was made to use.
Missing params, inconsistent param types, missing method definitions, check all of this out.
In my case:
public class California {
#override
public String transportation(String transportationType, String transportationId, String transportationArea)
{
return transportationType;
} public static void main(String[] args) {
California c = new California();
}
}
interface Oakland{
String transportation(String transportationType, String transportationId);
}
This did not compile because transportation method missed one of the params!

How to subclass this without repeating code

I have class Dad with subclass Son. I'd like to create a subclass of Dad and a subclass of Son that overrides a method of Dad.
What would be the best way of doing this without repeating code? I can not modify Dad and Son.
Given...
public class Dad {
public void doSomething() {}
}
public class Son extends Dad {
}
...I'd like to create...
public class DadSubclass extends Dad {
#Overrides
public void doSomething() {
// My code
}
}
public class SonSubclass extends Son {
#Overrides
public void doSomething() {
// My code
}
}
...without repeating // My code.
The obvious solution would be to create a helper class and call it for both, but this is problematic if I want to call protected methods, and I'm not allowed to create the subclasses with the same package.
Is there a better solution?
Create a common helper class and call it.
Assuming your code isn't accessing member variables, I would just put this code in a static utility class. If this isn't the case, you can still do this by passing in a common superclass - that of 'Dad' public static void mycode(Dad d). If you need specific variables in the subclasses themselves, I would rethink your class structure.
What you really want here is something like this:
class DadSonSubclass extends Dad, Son {
public void doSomething() {
//mycode
}
}
This is multiple inheritance, which is not supported by Java. So your only option would be to create a helper/utility class, which is perfectly acceptable. If you need to call protected methods, just pass the Dad object in to the helper class and create public callback methods to access this info.
Maybe better, maybe not, depending on your point of view, but it can certainly be done. Put your code into a helper class, and use a callback to give that helper access to the protected methods it needs:
interface Callback {
void foo();
void bar();
void one();
void two();
}
class Helper {
static void helpMe(Callback callback) {
// My code
}
}
class DadSubclass extends Dad {
#Override
public void doSomething() {
Helper.helpMe(new Callback() {
public void foo() {
DadSubclass.this.foo();
}
public void bar() {
DadSubclass.this.bar();
}
public void one() {
throw new UnsupportedOperationException("one() doesn't exist in Dad");
}
public void two() {
throw new UnsupportedOperationException("two() doesn't exist in Dad");
}
});
}
}
class SonSubclass extends Son {
#Override
public void doSomething() {
Helper.helpMe(new Callback() {
public void foo() {
SonSubclass.this.foo();
}
public void bar() {
SonSubclass.this.bar();
}
public void one() {
SonSubclass.this.one();
}
public void two() {
SonSubclass.this.two();
}
});
}
}

Categories

Resources