For example, I have two classes:
class Foo
{
protected void say() {...};
}
class Bar extends Foo {.....}
Can I somehow allow the "say" method to be called only from the Bar and other derived classes, but not from the other classes in Foo's package.
No, protected mean, protected member can be accessed in the same package and all subclasses in any package. If you want to restrict the access in package level, move that class into a separate package.
There's no such accessor in Java that meet your needs, and AFAIK it's not possible to implement that restriction (in a simple way, that is, and besides Kugathasan's solution).
There isn't a way how you can do this in java.
Related
I have the following situation.
package A;
class SampleClass
{
static interface sampleInterface
{
....
}
}
Now when I try to import the sampleInterface from another package , jDev says 'access not allowed'. What could be the problem?
Currently, the interface is seen as package-private (there's no visibility modifier, so that's the default). Place public on the outer class and the interface, and it will become visible to other classes.
Just be careful - if you get caught in a situation where you have to do this:
public class Alpha extends Alpha.IAlpha {
public void doNothing();
public static interface IAlpha {
public void doNothing();
}
}
...you'll have an issue with cyclic inheritance, and your class won't compile. In fact, you won't be able to use the interface at all.
Keep these rules in mind for exposing interfaces, classes, or enums:
If you only need an inner class, interface, or enum for that particular object, then it's fine to declare it as static.
If you need a class, interface, or enum accessible from anywhere but that object, then it's best to move it out of the inner class, and into its own file.
In general, interfaces are seen as APIs to conform by - there's really no benefit in having them as nested unless the scope of them is extremely narrow.
Change visibility of the class and the interface to public. It will work for sure.
When you declare a class without a access specifier it is by package-default. This means you can access that class in that package only.
If you want to access class from another package, make class public, i.e.
public class SampleClass
Similarly, in your case, as you want to access the Interface as well, you have to make that interface public as well.
This will solve your problem.
I have a superclass like this which I expect alot of classes to inherit:
public abstract class Super {
protected Object myField; //Not used anywhere in this class
//a load more code here which does useful stuff
}
All these classes will need to use an instance of myField. However the superclass does not. Have I made a bad design decision somewhere?
Not necessarily. If all the subclasses need the same field for the same reason, then that's no different than providing any other common functionality in a base class. as your classes grow you may find that you add common functionality which uses this field (e.g. referencing it in an equals/hashCode method).
Now, if the field is of type Object and each sub-class shoves something completely different into it, i would consider that a code smell.
Well IMHO, a field should not be present in a class if it's not really used by that class. What it seems to me that you really want here is to have a base class that tells its subclasses "you should ALL have some way of keeping state for X but I (the base class) will not modify that X state, in which case you should make an abstract method in order to convey that message, something like this:
public abstract class Super {
protected abstract Object getMyField();
}
It's hard to say with such a vague description, but it would seem like you could do some generalization and push some common code up into your superclass. If your subclasses are doing something similar with the field then some commonality could be found (using template methods or strategies to handle subclass-specific differences), otherwise if every subclass is doing something different with it then what's the point of using a common field?
No, I don't think so. Abstract class serve that purpose (Have common functionality in base class and let subclass implement only specific required functionality).
So, if you don't use that field in class Super - why do you need it there?
Perhaps your super class would provide an interface to interact with this field in generic way, for example:
public abstract class Super<T> {
protected T myField;
public T getField() {
return myField;
}
}
public class Child extends Super<String> {
public Child( String label ) {
super.myField = label;
}
}
As stated in this tuturial
A protected field or method is accessible to the class itself, its subclasses, and classes in the same package.
This means that the protected fields have been designed precisely to have these characteristics.
Just on a lighter note The only thing common in your hirarchy is one field then you should get rid of abstract class and Create one Marker Interface.
I have 2 classes A and B.
class A implements Constants{
private int state;
}
class B implements Constants{
foo(){
//want to set state variable of class A like this
state = state1
}
}
interface Constants{
public final int state1;
public final int state2;
}
I don't want to have an instance of class A in class B. How should I do this?
If I have a function to set the variable in the interface, then both the classes must implement this function. That would be wrong right? Because then 2 definitions for the same function would conflict?
There is nothing called functions in java. They are methods.
You can have getters and setters in your classes for the properties to set and get them from external classes.
Your question is unclear.
If your B class extends the A class, then through the constructor of the B class, you can set the properties of the A class that is the super class.
Hope it helps!
Having an interface does not mean that the variable will be shared between the classes, it is more of a way to define classes that MUST override the functions in the interface. You can read the very basics on them here. To share a variable between two classes, you can either make the variable static and put it in another class that both your classes extend (in effect a global variable, which is bad practice and not thread safe), or have one of the classes have an instance of the other and call getters/setters.
EDIT: there is a similar question here that shows you what I mean about the static variable.
You generally want to avoid writing any method in a class that attempts to alter the internal state of another class. Whatever trick you come up with to accomplish such a thing, you are breaking the principle of encapsulation which is the whole reason for using classes in the first place.
If there is some state that you wish to have accessible from multiple classes, I would recommend breaking that state out into it's own class and have each of the two classes interact with it through getter/setter or utility methods.
Is it possible that different child classes have different visibilities to the methods of the parent. Suppose there is a class A which has 10 methods defined. It has two different child ClassB and ClassC. Is it possible that that ClassB and ClassC has access to different methods of ClassA. Like ClassB has access to only 6 of 10 methods defined in ClassA and ClassC has acess only to the other 4 methods of ClassA? ClassB and ClassC are in same package.
Thanks,
Asit
I don't think it is possible with classes. To segregate functionality you should use interfaces instead of extending classes.
It is quite likely that your class A is violating the Single Responsibility Principal if you need to divide methods like that.
Then look to use composition instead of inheritance to compose complex classes from the simpler ones. Also take a look at the strategy pattern.
Divide your functionality in interfaces like this -
public interface IFlyable
{
void FlapWings();
void Fly();
}
public interface IHuntingAnimal
{
void Hunt();
}
Then implement your classes like this -
public class Duck : IFlyable { ...
public class Eagle : IFlyable, IHuntingAnimal { ...
public class Tiger : IHuntingAnimal { ..
Note: The example is in C#. You need to work out the java equivalent.
You can do such a thing with interfaces, but not concrete classes.
Adapter or Decorator pattern will help you.
From you wrote, i suppose what you have is
package first;
class A {
protected methodA() {...}
private methodB() {...}
public methodC() {...}
methodD() {...}
}
package second;
class B extends A {...}
class C extends A {...}
In this case, B and C will only see methods methodA and methodC from class A.
methodB is private, so unreachable
methodD is package protected, that's to say restricted to classes in same packgae (a weird way to have an equivalent of the C++ friend keyword, I realize now), and as a consequence not visible outside of packgae first.
not really understood what do you mean...
it is generally possible that methods of a parent class have different access modifiers as possible inherent classes. but with one condition (citation from lang spec):
The access modifier of an overriding or hiding method must provide at least as much access as the overridden or hidden method, or a compile-time error occurs.
you cannot coarct usability of a class, i.e. if a method from your class A was "protected" then you can declare an overriding method in your class B as "public". but it doesn't work vice-versa
I don't know the context of your question so I can't comment as to whether your design is sound and by extension, whether your motivation for this is justified. Since others have already taken the stance that your ClassA requires refactoring, I'm going to do the opposite and assume that it's a sensible class with a single well-defined purpose and it doesn't require subdivision.
In which case, why not use the object adapter pattern to achieve what you're after? You can expose the ClassA methods you want to in your ClassB and ClassC adapters by implementing wrapper methods which forward invocations to your ClassA adaptee. And of course, you can optionally extend those methods.
This answer is predicated on your use of the term child class
Short answer no
Longer answer
In this situation:
class Base has the following methods: method1, method2, method3
There is no way, using Java, to setup the following situation:
class Derived1 (this class extends class Base) can access method1 and method2, but cannot access method3.
class Derived2 (this class extends class Base) can access method1, method2, and method3.
Both classes are in the same package.
In Java, when one class extends another class these things always apply:
The derived class may call every public method of the base class.
The derived class may call every protected method of the base class.
The derived class may not call any private method of the base class.
If the derived class is in the same package as the base class,
the derived class may call every package access method of the base class.
as for my observation when the class itself is having default access modifier, what is the use of having public methods in it. the java compiler could have stopped using public methods in default class. is there any reason for that?
The non-public class might implement a public interface. This would mean that classes outside of the package could not create an instance of this class or create references of that type, but they would still be able to invoke methods on it if passed an instance.
For example, a public factory class might create an instance of an non-public class in its package and return it.
One reason: if your class implements some interface (or extends some abstract class with abstract public methods), then you may not reduce the visibility of those implemented methods.
It is a beautiful combination of Security and Usability packed in one.
I would mark a Class with default access if I want it to have a, well, package access (so that no other package can use it or better change the code) and marking a method public, I am making the method accessible to all other classes regardless of the package they belong to.
How does that help? A class which is secure enough to perform all the complex code implementation and usable enough to give the output to the user who wants to use it.
How can anyone use that? Well you write code to help them use it by creating a public class which extends this default class. You Instantiate this public Subclass in any package (after importing of-course) and this has all the methods marked public.
You have a class which does your magic which everyone can use without giving anyone else a hint of how you got it done!