I have build a subclass from a class in Java that has private methods which I want to access in the subclass, I cannot change or edit the superclass. The problem is of course they are private. Suppose I have written the superclass by myself and there were certain reasons why these methods have to be private. I could copy the code in the subclass. But is there a better way (without producing so much lines of code) to get able to work with them when writing a subclass?
Ignoring that your reasons for wanting to do this are potentially very bad (there's no contract for your usage of private variables, so there are no guarantees that they won't change, or disappear completely!) you could probably do what you want using reflection:
Using:
http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getDeclaredField(java.lang.String)
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible(boolean)
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html#get(java.lang.Object)
Class c = object.getClass();
Field field = c.getDeclaredField("somePrivateInstanceVariable");
field.setAccessible(true);
Object someValue = field.get(object);
I just want to emphasise that you should consider the reasons for doing this and decide against it! If you own the code that you are extending, consider if you should instead make the field protected instead of private. Remember, hooking into code you're not supposed to have access to breaks OOP principles (you're circumventing encapsulation) and there are no guarantees the code your application depends on won't disappear in an update to the library (so you're also locking yourself down to a fixed version of the lib).
So you tried with "extends" to inherit the methods from the superclass. And of course they are private, but you can use them in the sublass. Making them abstract would force you to rewrite every in private, i see no other option.
Make super class method's protected. It would be only accessible from sub-class and package.
private modifier's are only accessible with in class.
In your case you should declare the private method as protected instead. Read this for more details on the subject.
Related
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
Say I have a class Animal and then a bunch of sub-classes that extend Animal. Say I want to have a common field called name that should also exist in each child class. What is the proper way to include and initialize this field in each sub-class?
1) Declare the field in the parent as protected, and then initialize it inside of each sub-class. If I do it this way, is it proper to refer to the field as super.variable or simply variable? Personally to me, using super makes it more obvious that the field is declared in the parent. (This is what I am currently doing)
2) Declare the field in the parent as private and then create getters and setters to access the field
3) Just declare and initialize the same variable in each sub-class
4) Another method I'm missing?
Thanks for the help. I understand this question is fairly basic, but I'm curious of what the most proper style is.
Edit:
I'm not to sure if you guys will see this, but here is a follow up question.
Is there any good way to ensure that the sub-classes initialize the field?
The answer depends on whether you need to control access to that field for correctness (e.g., to make sure that some other field gets updated at the same time). If it's okay for subclasses to twiddle the field directly, then just use protected. If you need to perform additional checks or actions whenever the field is set, you should make it private to the superclass and make the subclass use the setter to ensure your logic is run. You shouldn't duplicate the field if you know that it'll always be needed; if you're not sure, then you should consider using an interface Animal and putting the field on an AbstractAnimal implements Animal.
In Java, you don't use super for anything except to call the superclass's version of a method. Just access protected fields directly; that's what they're there for, and your development environment will keep track of where they're declared if you need to know.
I vote for 2:
Create a private field, and have setters and getters (which can be protected to make them accessible only to subclasses).
Other options if you don't need a setter (just a getter):
4) Abstract getter and leave it up to the subclass how to implement it
5) private final field, set by abstract class constructor, and a getter.
I always make fields protected fields, since this helps debuggability & extensibility, and put public getters & setters on them to make a 'property'.
(Private fields in various open-source libraries, Swing components etc have repeatedly been a hindrance to me when trying to do quite legitimate debugging/ extension engineering. So I'm fairly anti- them.)
If I'm concerned about traceability, where there is possible behaviour or errors involved (such as values being got & cached), I might access the variable in subclasses via the getter.
I always use this.name when writing to variables -- it works well for code clarity, and it simplifies parameter-naming in setters. (Use just name for the parameter & this.name for the field.)
I don't use this when reading variables -- it's the writes I want to be clear about. For collections, I suffix the field with List or map or whatever ie childList -- but the parameter and locals are "children".
I never use super when referring to variables. Super would only make sense to disambiguate inherited & declared variables with the same name, which you can legally do -- but is almost guaranteed to be erroneous for code style, clarity & tends to lead to bugs.
I also like to make most properties mutable -- rather than settable only at construction. This helps if you ever want to use Hibernate, or persist the data. Over-reliance on constructor initialization tends to evolve into difficulties -- large & brittle call-signatures, inability to use the class for partly-formed data or "special value" answers, and order-of-init problems.
I think it depends on the situation. If the name field should be publicly accessible, I would declare the field as private and then make public get/set methods. Sometimes you want to expose fields on the base class as part of the public interface of the derived classes.
If the name field should only be used inside the derived classes I would just go with a protected field.
If you want to be sure that a subclass initializes a field add a parameter in the base class constructor, then initialize the field in the base class using the argument supplied by the derived classes constructor.
I usually using option 2 (private + accessors - protected,not necessary public) to have a chance to customize variable access.
About your edit: Force in constructor name if it is a mandatory requirement
Animal(String name) {
this.name = name;
}
or
String getName() {
if(null == name){
name = initializeName();
}
return name;
}
and make initializeName() abstract
i am still reading factory patterns on head first. We have an pizzaStore example and trying to localize our pizzaStore class to let franchies freedom to have their own regional style.
To do this, we changed to pizzaStore class to abstract class, and moved our factory object to "abstract createPizza(String type);" method. It is ok, i understood why.
If you look at the picture, i underlined the sentence. What it means ? " if we really want to enforce, we could make the method final ? "
The point is that subclasses are supposed to implement createPizza, but are required by contract to not override orderPizza, just call it. This policy can be enforced by making the method final.
When you design a class for inheritance, you must generally take care of all the details involved in how exactly the class is supposed to be extended.
If you make a method final classes inheriting the method cannot overwrite it. This ensures that the implementation in PizzaStore is used by all the subclasses.
Source: http://docs.oracle.com/javase/tutorial/java/IandI/final.html
Declaring a method as final, prevents the subclasses from overidding it.
If you make orderPizza method final, you cant override in your subclasses, but you can still access them. methods marked with final cant be overriden in your subclass.
Final methods cannot be overridden thus any inheriting class has the same method, they are enforced to have that same method.
This means that ChicagoStylePizzaStore is not allowed to override orderPizza().
The java final keyword: final orderPizza() enforced that the sub classes cannot overide that method.
Class Chicago then has to call orderPizza() from PizzaStorre() and not from an own method with same name.
I am fairly new to java development and wounder how I can modify an existing Android class. I would like to change some of the methods in Notification.Builder class in Android (https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/Notification.java).
Specifically do I want to change getNotification(), but in the new implementation I need access to the private fields (e.g., mWhen, mSmallIcon).
I have tried to extend the class, but then I don't have access to the private fields of the superclass (i.e., mWhen, mSmallIcon).
What is the best practice to change the method, is it to copy the source code and modify it?
Update:
To be more precise: how can I change a single method in an existing class and still have access to the private fields of the existing class?
Thanks for all responses!
You could simply call super.getNotification() in your overriden method and modify the resulting object before returning it.
A private (inner) class, method or field are only referenced from within the class in which it is declared.
But you also can declare your own variables and work with it as you wish
The best practice is not to override methods (from third-party classes which were not designed to be overridden), but to create a new class/method which wraps the third-party class. Google for these: "fragile base class problem", "composition over inheritance".
I have tried to extend the class, but then I don't have access to the private fields of the superclass (i.e., mWhen, mSmallIcon).
In the particular class you're extending there are a limited number of methods that set the values of these fields. You can override those methods to hold onto copies of the values in new fields in your subclass which you can then use in your override of getNotification().
This is something of a hack, and wouldn't be workable with a more complex class.
Another hack is to use reflection and invoke setAccessible(true) on the field objects. This also may not be workable depending on security constraints.
If you say exactly the change you're trying to make, there might be a better way.
I have read from literature that a variable shouldn't be declared protected just so it could remain visible in the inheritance tree.
Why is so?
Fields are implementation details - they should not generally be regarded as part of the API - that way you get to change exactly how things are stored later on. If you make a field protected, it will be available to subclasses, rather than the subclass only getting to see an API which they can rely on.
What if you want to restrict which values are valid on that field at a later date? When it's protected, you don't get any validation or anything similar. Subclasses could put any old rubbish in there. If you keep it private and give a protected setter method, you can apply appropriate validation.
In short: regard your clients-through-subclassing as clients in much the same way as your clients-through-calling. Give them an API to work with, and keep your implementation details private.
Most of the times, when I create inheritance, I make sure that all variables are private. Whenever the inherited class wants to have something from the super class, he can get the values with the getter methods.
If everyone could get and set a variable in the hardcore way, there is no way to rely on extra code that should be run when you set that variable. The super class is giving away his own responsibilities.
Its the concept of Inheritance. If class A inherits from class B, then it has access to Protected variables and functions. so, if you don't want to give an access to any other class, then go ahead and declare it as Private.