I have code very much like the following.
package my.pkg;
public abstract class X {
private CapableField field;
public abstract void doSomething();
public X(CapableField fieldValue) {
this.field = fieldValue;
}
}
And:
package my.pkg.sub;
public class Y extends my.pkg.X {
public void doSomething() {
this.field.doSomething();
}
}
Why is this even legal code in Java? I thought "private" meant that the field will not be directly accessible in subclasses, and that this was a fairly basic tenet of class inheritance. Making X concrete instead of abstract changes nothing.
What do I do if I specifically want a field, or member function, to be accessible only inside the class where it is defined, and not in some random subclass of the defining class?
This is not true. Most likely you've actually definied Y as an inner class. This way the private fields of the outer class are indeed visible like that.
Doesn't compile for me too! I suspect your Java implementation.
This is impossible. May be you missed something when you explain your question.
private members are not visible in inheritance except in inner class scope. If you want them to be accessed by the subclass then declare them as protected. or use setters and getters.
and in your code you used package keyword in your package declaration which is not allowed and gives compilation error.
Make sure that your classes in two different files. for example X.java and Y.java and y not an inner class
Related
How can I create a member that should be available only to my sub classes in java ?
static class XX {
private static int p = 10; //p is only accessible to TT
static class TT {
static public int getT() {
return p;
}
}
}
Assuming your child classes are subclasses, any public variable is accessible to them. If you wish to access private variables from a subclass, than you have to change them to protected.
Assuming that when you say "variable", you are talking about a member of some class. E.g.,
class Parent {
SomeType myVariable;
...
}
Assuming that when you say my child classes, you are talking about the extends relationship in Java. E.g.,
class Child extends Parent {
...
}
In that case, you can't have exactly what you ask for, but maybe you can have what you need.
If you declare the member to be protected, then it will be visible in any child class, but it will also be visible in any other class that belongs to the same package, regardless of whether the other class is a child or not.
class Parent {
protected SomeType myVariable;
...
}
IMO, there's not much use for protected. It serves as a suggestion that other programmers should not try to use it in a class that does not inherit from the parent, but so what?
If you see a private member in some class, then you are assured that no code outside of the source file where you see it can possibly depend on it.
If you see a member with default access (i.e., neither public, nor private, nor protected), then you know that any code that depends on it must be declared in the same package. Nothing prevents some other programmer somewhere in the world from declaring his own code in your package, but if he/she does, then she or he is being stupid, and when you release a new version that breaks his/her application, that's not your problem.
If you see a member with public or protected access, then you have to assume that people you don't know, and people you will never meet are depending on you to not change it.
This question already has answers here:
Should we declare a public constructor when the class is declared as package private?
(2 answers)
Closed 8 years ago.
I am new to Java. I want to know what it is the use of public constructor in a private class. Private class inside the class can be initialized from the same class then what it is the use to make the constructor of private class to public?
public class MainActivity extends Activity {
private class AcceptThread extends Thread {
public AcceptThread() {
}
}
}
There doesn't seems to be any real use case for public or protected modifiers with private classes. If you have multiple classes in a single file though (but not nested or local), you need non-private constructors to instantiate the private classes.
// X.java
public class X {
private Y y = new Y();
}
class Y {
Y () {
// if this were private, X wouldn't be able to create an instance of Y
}
}
Actually default or protected visibility would be enough to create an instance in this case. All non-private modifiers allow you to create instances from other classes within the same package but practically have the same visibility.
The private class isn't visible to classes outside of the package, so public methods have no use here.
The private class can't be extended by classes outside of the package, so protected has no use either.
Even when using reflections, a public constructor is not accessible by default from other packages and will throw a IllegalAccessException. It checks the class visibility first, then the member visibility.
The default modifier is the most restrictive modifier that allows you to directly call the constructor from other classes, so package-private seems to be the most appropriate visibility for the constructor and also any other non-private methods. This also has the advantage that if you change the class visibility in the future, you don't accidentally expose the constructor or any methods to the public.
You know, I ask myself this question almost each time I make a private inner class, but I always assumed that there could be some (possibly contrived) reason for a public constructor. So #kapep 's answer got me tingling and encouraged to find ways to require a public constructor on a private inner class, but the more I think and experiment with it, the more I think the holes are plugged.
Possible angles, all of which failed me:
Serialisation: When unmarshalling an object whose superclass is not serializable, the superclass needs a no-arg constructor accessible from the subclass. So, protected should always suffice here.
Reflective tools: Code that uses reflection to get the inner class constructor through a returned instance. Fails because the type visibility is checked first, as #kapep pointed out, though it leaves a rather interesting error message:
Exception in thread "main" java.lang.IllegalAccessException: Class A can not access a member of class contrived.B$C with modifiers "public"
Inner class extension shenanigans: Don't try this at home:
package a;
class Outer {
private class Inner {
}
}
package b;
// compile error: Outer.Inner has private access in Outer
class Extender extends a.Outer.Inner {
Extender(a.Outer outer) {
outer.super();
}
}
Seemed promising at first, but I didn't get too far with that one.
In the end, I could not find a way to make a public constructor on a private inner class useful.
Then why is this technically legal despite having no use? Probably because the compiler automagically inserts a no-arg public constructor when no other constructor is provided. Hence the language should not disallow this constructs. More of an artefact than a reason, though.
What does it means to declare a non-static inner class as final?
I have tried many links on google and stackoverflow.com as well but all of them seem to be dealing about inner classes accessing final members not final inner classes itself.
I found this link on google but even it doesn't explains it.
Thanx in advance!
There is no semantic difference between making a top-level class final and making an inner class final: it tells the compiler that you cannot inherit from the class. Marking classes final is sometimes done to let the compiler skip a virtual table lookup, but this is often regarded as premature micro-optimization.
It has the same semantics as an outer class being declared final: the class cannot be extended.
Consider this example:
public class MyClass {
public class A {
}
public class B extends A {
}
}
If you add the final modifier to A it will generate a compilation error.
Well, inner classes are not any way different from outer classes in that context. So the following code is perfectly valid.
class Outer {
int some_member;
class Inner {
void method();
}
}
class OuterExtendsInner extends Outer.Inner{
}
As we all know, the purpose of declaring a class final is that we prevent any outside intruder from subclassing the class and exploit its facilities, the same way we can do in case of inner classes.
I want to create a class, ClassB, as inner class of ClassA, but I want to write down outside ClassA.java file.
How can I do this?
It will be a lot of inner class, and ClassA.java file will be enormous.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
Thanks.
The simple answer, is no you cannot.
By virtue of being an inner class, the class has to be inside the scope of the parent class.
If your class is really going to be enormous, it probably says something about the design of your class. Are you making proper use of encapsulation?
Put all your classes in a package and define the classes to be package private.
package com.example.here
class Hello{
//...
}
Notice the absence of the keyword public? You will only be able to create an instance of the class Hello if the class creating it is in the com.example.here package.
Try the following ...
Hand over a reference of the outer-class to the no-longer-inner-class
Use packages and make the no-longer-inner-class package-private (Jeremy's answer)
In the very rarest of cases, it might actually be best to go with inner classes, and at the same time have them do work elsewhere. If this really is you, please read on ...
How to keep inner classes small
a) Extend from outer classes
class Outer {
class SomeInnerClass extends SomeClass {
// More specific code here
}
}
class SomeClass {
// A lot of generic code here (in a different file)
}
b) Use abstract methods
One of the (more correct) reasons for using inner classes, usually has to do with the use of the exact instance of the outer-class. To tackle it in a generic fashion in the base class, use abstract getters.
abstract class SomeClass {
protected abstract SpecificData getSpecificData();
void someMethod() {
SpecificData specificData = getSpecificData();
// Do work with the "specific data" here ...
}
}
class Outer {
private SpecificData mSpecificData = new SpecificData();
class SomeInnerClass extends SomeClass {
#Override
protected SpecificData getSpecificData() {
return OuterClass.mSpecificData;
}
}
}
I think you get the idea, ... You might also consider using some GeneralData class or interface (within SomeClass) instead, and have getSpecificData() return a more specific (descended-)instance of it.
Again: This can be terribly misused to create very bad unreadable code, but it also can be used for very nice patters under the right circumstances, anyways it should answer the original question.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
If you want to restrict access to a single class, you can put them all in a new package. You will need to move the designated class that is allowed access into this packate, too. For the new classes, you can restrict access by using the default access level (no public/private/protected modifier). This will make them accessible only to the classes in their package. The specified class that is allowed access can be made public so that it can be used outside this new package.
Note: You have the option of restricting the visibility of the class or the visibility of the constructor.
I'm trying to use extends (inheritance) in Java. I made a quick abstract class to extend from, and then extended it. However my IDE now is saying that "An enclosing instance that contains abstract_class is required" and gives my constructor for the derived classes big error lines. What on earth is it going on about? The abstract class doesn't have or need any sort of constructor.
Just for reference, I'm using extends rather than implements in part because the implementation details that I don't want to have to maintain for every derived class which are identical involve using reflection on this.
Edit: I've read some of the responses. What in God's name is a static (or non-static, for that matter) class? And just to irritate all of you, it didn't solve the problem.
// some_class.java
public class some_class {
public static abstract class abstract_class {
...
}
...
}
// Model.java
public class Model extends some_class.abstract_class {
public Model(...) {
// No enclosing instance! Critical error.
...
}
...
}
And I thought that C++'s header files were bad.
The code you posted seems to compile just fine for me. Try doing a clean build in your IDE and it should work.
Just for your own curiosity, Java has 2 types of inner classes: static and regular or (non-static). If you don't include the static keyword for an inner class definition, it means that an instance of that class will always require an instance of the parent class. For ex:
public class MyClassOuter {
//...
public class MyClassInner {
//..
}
}
If you write that, it is understood that any instance of MyClassInner will have an implicit reference to an instance of MyClassOuter.
Static, on the other, hand implies no such thing. It is just a class definition that happens to be inside another class definition. The outer class is used almost like a package (though not quite).
if you have
interface MyInterface
{
abstract class MyAbstractClass {
// ...
}
}
and then you try
class ConcreteClass extends MyAbstractClass {
}
You will get the error described. The fix is to either move MyAbstractClass to a top-level class (put it in it's own file - not strictly necessary for non-public classes, but keeps the code organized.) Alternatively, add the static modifier to the MyAbstractClass declaration.
The "enclosing instance" message almost certainly implies that you have a (non-static) inner class for your superclass. In most cases, inner classes can and should be static - that's likely the best workaround here. Alternatively, as the message says, you will need to use an enclosing instance of the "outer" class, if your parent really makes sense as a non-static inner class.
Posting some code will help disambiguate between these causes and suggest the best way to resolve it. I'll also be able to give examples of the resolutions with the right class names - currently I don't think arbitrary names will help that much as it sounds like you hadn't identified the inner/outer class issue.
You need to in your child class add in the constructor super() that super class can be created.
class A{
.
.
.
class B{
. . .
}
}
if you want to access the Class B and it it is not static inner class you can write the code as
A.B objOfB = new A(). new B();