Overrite method from external or private class - java

I have some method that use method from external library (mvn). So I cannot adit it. When Im trying override that method im getting:
void is not public in *class; cannot be accessed error from outside
package
dont have access to that external library
The question in how to override method from external class (library) that extends abstract class or class with private methods.
logout = new Class(arg1, arg2) {
#Override
public boolean ovMethod(){
someMethod(true);
}
Method ovMethod() from (external class, downloaded by maven) Class:
Class extends AbstractClass {
public abstract class AbstractClass {
void someMethod(boolean arg) {
}
}
}

Generally speaking, you shouldn't override methods that are not meant to be overridden. But as a last resort, if the method is package-private (a.k.a. default visibility) you can create your own class in the same package so it has permission to override the method:
package same.package_as.superclass;
public class MyClass extends Class {
#Override
void someMethod(boolean arg) {
// custom implementation
}
}

Related

Java method that can't be callable but can be overridden

If I don't want that a method on my class can be called, I just make it private.
But if I want to allow that method to be overridden, I have to make it protected
Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)
Use case:
abstract class Super {
protected void finalize() {
}
public final void doThings() {
// do stuff
finalize();
}
}
and whoever wanted to extend the class:
class Sub extends Super {
#Override
protected void finalize() {
closeSockets();
alertSomeone();
}
}
But I don't want other classes calling mySub.finalize();
Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:
public class Super {
private final Runnable subClassCode;
public Super(Runnable finalizeCode) {
subClassCode = finalizeCode;
}
public final void doThings() {
// do stuff
subClassCode.run();
}
}
public class Sub extends Super {
public Sub() {
super(() -> {
// code to be executed in doThings()
});
}
}
You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.

Instantiate an inner class inherited with protected access specifier

I wanted to make the following exercise from Bruce Eckel's TIJ on inner classes:
Create an interface with at least one method, in its own package.
Create a class in a separate package. Add a protected inner class
that implements the interface. In a third package, inherit from
your class and, inside a method, return an object of the protected
inner class, upcasting to the interface during the return.
Here's my implementation:
first, the interface:
package workers;
public interface Employable {
void work();
}
then, a class with an inner class implementing the interface:
package second;
import workers.Employable;
public class WorkersClass {
protected class Worker implements Employable {
#Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
and finally the inherited class:
package third;
import second.WorkersClass;
import workers.Employable;
public class Third extends WorkersClass {
Employable getWorker() {
return new Worker();//the line is reported to be incorrect
}
}
IDEA underlines the line with Worker() in getWorker and suggests to make the Worker class public. But why? It's protected that's why successors of WorkersClass can instantiate the Worker class in their methods. Do I misunderstand something?
The problem is not all with access specifier.
When you don't provide any constructor in a class, the compiler automatically inserts a default, no-args constructor for you
That's not true here in this case. Because the compiled inner class doesn't get the default constructor since it gets compiled as outer$inner and for that inner there is no default constructor provided by compiler.
Provide a default no org constructor manually and see the magic :)
package second;
import workers.Employable;
public class WorkersClass {
protected class Worker implements Employable {
public Worker() {
// TODO Auto-generated constructor stub
}
#Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
modify WorkersClass
public class WorkersClass {
protected class Worker implements Employable {
public Worker(){}
#Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}
}
Your Third class inherits WorkersClass and not Worker.
Java does not really consider inner classes, it is a simple hack introduced in Java 1.1. The compiler generates class Worker "outside" of class WorkersClass, but in the same package.
That's why, in order to implement a new Worker instance from a Third method, you need to add a public constructor to Worker:
protected class Worker implements Employable {
public Worker(){
}
#Override
public void work() {
System.out.println("Hello, I'm a worker!");
}
}

Could we call super.someMethod() in derived class from an abstract class?

Could we call super.someMethod() in derived class from an abstract class?
for in stance:
abstarct class TestBase{
void nonabstractMethod(){
....
}
}
Then derived class:
class Child extend TestBase{
void callFunction(){
}
void nonabstractMethos(){
super.nonabstractMethos();
}
}
I assume this can be done. But if we have an abstract method then it cannot be called because of no implementation, am i correct?
The short answer: yes.
You can always call a public or protected super method. Like any (instance) method in java, it will be handled polimorphicly, and a concrete implementation will be called, either of the super's class or from the derived class if it overrides it.
Yes you are correct. If you are extending an abstract class having abstract method, you can't call super.thatMethod();
Consider the following example
public class RSAService {
protected void doRSA(){}
}
class MyService extends RSAService{
public void myService(){
super.doRSA(); //Works fine
}
}
This will work as the doRSA() is accessible from the MyService. Same for public but not for private
But
public abstract class RSAService {
protected abstract void doRSA();
}
class MyServe extends RSAService{
public void myService(){
super.doRSA(); //This won't work
}
#Override
protected void doRSA() {
}
}
Now consider this case, where you can call the super.superClassMethod() from your subclass
public abstract class RSAService {
protected void doRSA(){}
}
class MyService extends RSAService{
public void myService(){
}
#Override
protected void doRSA() {
super.doRSA();
}
}
So if you are overriding a super class method you can call the method using super. Consider this Java Specification link for more clarification
Your example will work if both classes are in the same package.
If that is not the case, then you should declare the method protected or public, something like:
abstract class TestBase{
protected void nonabstractMethod(){
....
}
}
If your method is abstract, then you can't call it, for example:
abstract protected void abstractMethod();

Calling another classes method with the object of the class

Class A implements interface I that requires method doAction(). If I call a method from class A of class B, and pass "this"(class A) into that method, how can I call a method that lives in class A from the method in class B? For example:
class A implements I {
public void start() {
B.myMethod(this);
}
#Override
public void doAction() {
// Do stuff...
}
}
Class B {
public void myMehtod(Class theClass) { //How would I accept 'this', and...
theClass.doAction(); //How would I call the method?
}
}
I am doing this for purposes of a custom library, without knowing the exact name of the class that extends I.
This is a very basic question about how interfaces work. I'd recommend trying to find a tutorial about them.
Anyway, all you have to do is declare a parameter with the interface as its type. You can invoke interface methods on variables of the interface type (or any sub interface or class that implements that interface).
Class B {
public void myMethod(I theClass) {
theClass.doAction();
}
}

Overriding Protected Methods

I'm new to Java and I have a very basic question.
I have 2 Parent Class under the same package. Animal Abstract Class and the Machine Class.
Now, the Animal Abstract Class has a protected method. I'm aware that protected methods are accessible if the classes are under the same package.
I can access that protected method in my Machine Class, and the question is.. Is it possible to override that protected method? Without extending the Animal Class.
protected - Can be overridden by subclasses, whether they are in the same package or not
default (no access modifier) - can only be accessed or overridden if both the classes are in the same package
You can only override methods through extension.
You can override a protected method with an anonymous subclass, if you like. E.g.
public class Animal {
protected String getSound() {
return "(Silence)";
}
public void speak() {
System.out.println(getSound());
}
}
In another class:
public static void main(String ... args) {
Animal dog = new Animal() {
#Override
protected String getSound() {
return "Woof!";
}
}
dog.speak();
}
Will output:
Woof!
No , Overriding means inherit the behavior from parent class and that is not possible without extending the class.
public class PClass
{
protected boolean methodA()
{
return true;
}
}
public class CClass extends PClass
{
protected boolean methodA()
{
return false;
}
}
Run the code below to test it
public static void main(String[] args)
{
PClass pc = new CClass();
System.out.println(pc.methodA());
}
O/p=false
here we are overriding the behavior of methodA
In order to override a method you have to extend that class. That's what overriding means: having a method with the same signature as the super-class.
Overriding by definition says..
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.
So AFAIK if you don't extend the super class there is no way to override the method.

Categories