Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to hide or lower access to Inherited Methods in Java?

I have a class structure where I would like some methods in a base class to be accessible from classes derived directly from the base class, but not classes derived from derived classes. According to the Java Language specification it is possible to override access specifications on inherited methods to make them more public, but not more private. For example, this is the gist of what I need to do, but is illegal:

// Defines myMethod
public class Base {
    protected void myMethod() {}
}

// Uses myMethod and then hides it.
public class DerivedOne extends Base {
    @Override
    private void myMethod();
}

// can't access myMethod.
public class DerivedTwo extends DerivedOne {

}

Is there any way to accomplish this?

Edited to explain why I would like to do this:

In this case the class structure is a data handling and import structure. It reads in and parses text files full of tabular data and then stores them in a database.

The base class is the base table class managing the database handling part of it. There is a fair amount of functionality contained in it that is common to all table types - as once they are in the database they become uniform.

The middle class is specific to the kind of table in the file being parsed, and has the table parsing and import logic. It needs access to some of the base class's database access functions.

The top level class is specific to the table and does nothing more than initialize the table's layout in a way the parent classes can understand. Also users of the base class do not need to see or access the database specific functions which the middle class do. In essence, I want to reveal these functions only to one level above the base class and no one else.

I ask because, although the code I posted as an example is illegal, there may be some other means to accomplish the same end. I'm asking if there is.

Perhaps hiding is the wrong way to phrase this - what I really need to do is expose some functionality that should be private to the base class to the class one level up in the hierarchy. Hiding would accomplish this - but I can see how hiding would be a problem. Is there another way to do this?

like image 473
Daniel Bingham Avatar asked Dec 14 '09 17:12

Daniel Bingham


People also ask

Can we reduce the visibility of the inherited method in Java?

You cannot reduce the visibility of a inherited method. Here parent class has func() method which is public and overridden by the subclass TestClass which is private.

Can inherited class access private members Java?

Private Members in a SuperclassA subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

How can we avoid a method from being inherited?

You can prevent a class from being subclassed by using the final keyword in the class's declaration. Similarly, you can prevent a method from being overridden by subclasses by declaring it as a final method. An abstract class can only be subclassed; it cannot be instantiated.

Which method hides a method in the superclass?

Static Methods If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.


1 Answers

I think the very nature of the problem as you've posed it exposes conceptual problems with your object model. You are trying to describe various separate responsibilities as "is a" relationships when actually what you should be doing is describing "has a" or "uses a" relationships. The very fact that you want to hide base class functionality from a child class tells me this problem doesn't actually map onto a three-tiered inheritance tree.

It sounds like you're describing a classic ORM problem. Let's look at this again and see if we can re-map it onto other concepts than strict "is a" inheritance, because I really think your problem isn't technical, it's conceptual:

You said:

The base class is the base table class managing the database handling part of it. There is a fair amount of functionality contained in it that is common to all table types - as once they are in the database they become uniform.

This could be more clear, but it sounds like we have one class that needs to manage the DB connection and common db operations. Following Single Responsibility, I think we're done here. You don't need to extend this class, you need to hand it to a class that needs to use its functionality.

The middle class is specific to the kind of table in the file being parsed, and has the table parsing and import logic. It needs access to some of the base class's database access functions.

The "middle class" here sounds a bit like a Data Mapper. This class doesn't need to extend the previous class, it needs to own a reference to it, perhaps injected on the constructor or a setter as an interface.

The top level class is specific to the table and does nothing more than initialize the table's layout in a way the parent classes can understand. Also users of the base class do not need to see or access the database specific functions which the middle class do. In essence, I want to reveal these functions only to one level above the base class and no one else.

I'm not clear why a high-level class seems to have knowledge of the db schema (at least that's what the phrase "initialize the table's layout" suggests to me), but again, if the relationship between the first two classes were encapsulation ("has a"/"uses a") instead of inheritance ("is a"), I don't think this would be a problem.

like image 53
Dave Sims Avatar answered Sep 20 '22 15:09

Dave Sims