im trying to create my little library. But i have little problem. I cant right understand how to hide some classes/methods from public usage.
Say i have structure :
-myPackage.com
-classA (public class example : public classA {...})
-classB (just a class example : class classB {...}
in this way when i add my aar file to android project. I can use from library only classA. classB hided(invisible for developer) and i cant call him (its ok). But classA can use functions from classB . Because its in same package. And its ok.
So how correctly create classes in another packages ?
-myPackage.com
-myHelpPackage
-classC (public class example: public class classC {...}
-classD (just a class example: class classD {...}
-classA (public class example : public classA {...})
-classB (just a class example : class classB {...}
in this way i have two public classes which developer can call
classA
classC
classD visible only for classA. So i cant call classD(functions) from classA.
Main question : how to achive it ?
I want to have only one classA to call. classC is ok. classD and classB should be invisible for developer. But visible only for classA. Anyone can help me with this ?
If you don't specify any access level modifier, e.g.:
package myPackage.com
class classA {
}
then the class will be package-private by default.
This means it is only visible to classes inside your package.
See also the documentation by Oracle here
This question has been answered in the comments by JakobJeremais, but in case it's not clear to anyone, or they skip over it because they only read top-level answers (understandable). If you have a package-private class in your aar, it will still be publicly accessible, so I would recommend nesting the class in whatever calls it, an you will be safe.
For instance, I had to extend EditText so that I could override just one method, and nothing else. Then I had to reference that from only one other class, but didn't want it accessible from whatever projects I added my library to. So I nested it, and now it's fine.
public class VisibleClass extends View {
public static HiddenClass extends EditTextCompat {
#Override
public void annoyingFunction() {
//Disable this function
}
}
}
I should note, though: The compiler isn't happy about accessing it from layout, so I suppose it hasn't really helped, so I wouldn't recommend it, for now. If you have time to tinker, go ahead, though.
Related
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.
First suppose that I have an abstract class, let's call it AbstractClass. Suppose
public abstract AbstractClass {
public abstract void F();
}
Suppose that I have a class, let's call it ClassA. ClassA extends AbstractClass. ClassA is saved in a folder. (It has to be loaded onto the classpath.) Now suppose that I am writing a new class within the program,
ClassB
and I want ClassB to be able to reference ClassA. Something along the lines of
public class ClassB extends AbstractClass {
ClassA A = new ClassA();
public void F() {
A.F();
}
}
Now, I have had no trouble using a class loader to get classA and use it dynamically. I have also had no problem writing a class like ClassA dynamically based on user input, compiling it within the program (using ecj.jar), and then loading it and calling methods from it.
I cannot figure out though how to reference a dynamically loaded class in a class that I am now writing and compiling dynamically. I don't know how to write the import, etc. Loading classA and putting
import classA;
into the classB.java file does not do the trick.
This is my first question on StackOverflow (long time reader), so go easy on me. Thanks in advance.
--
Context: A program that uses probability distributions entered by the user. I have an abstract class AbstractDistribution which has abstract methods for the distribution's CDF, PDF, inverse CDF, etc. So far this has worked well, dynamically writing compiling and loading distributions that extend AbstractDistribution, getting newInstance() of them and using them like any other class. However, if I have written and dynamically loaded a distribution Dist1, I want to be able to write a Dist2 that can call (for example), the PDF of Dist1.
Don't make B refer to A directly - make B refer to AbstractClass and take a reference to an instance in its constructor:
public class ClassB extends AbstractClass {
private final AbstractClass other;
public ClassB(AbstractClass other) {
this.other = other;
}
public void F() {
other.F();
}
}
At this point you need to work out how you're going to get hold of a reference to the other instance of AbstractClass (whether it's a ClassA or something else) but it does get rid of the direct dependency.
I'm sure there will be more exact details to work out, but if you can break the direct dependency like this, it should make the dynamic compilation aspect less of a problem.
I am stuck with a programming problem:
I have two Java projects, in my Eclipse IDE: ProjectA, and ProjectB.
ProjectB references ProjectA
I have declared a class in ProjectA: ClassA, and one in ProjectB: ClassB, such that:
public class ClassA{
public static Object foo(){
//blah
}
}
public class ClassB extends ClassA{
public static Object foo(){
//blah
}
}
I also have a class called ClientClass, in ProjectA. This ClientClass earlier used to create an instance of ClassA and use it. But now, based on an environment setting, the ClientClass should be provided the option to use ClassA or ClassB.
This seemed to be a problem for the AbstractFactory pattern, or so I thought.
I need to create a Factory that provides access to ClassA or ClassB. ClientClass should not be aware that it is ClassA or ClassB. This requires me to create an interface for ClassA and ClassB.
Issues I ran into:
ClientClass cannot refer to ClassB directly (no import statements / or new invocation), because ClassB is in a different project. This may be an Eclipse IDE restriction, but it also makes sense to me when viewing these two projects as jar files. A cyclic relationship is avoidable.
I cannot create a Factory interface and a common interface for ClassA & ClassB, and then via the AbstractFactory pattern provide a ClassAFactory or a ClassBFactory. This is because the methods to be invoked on ClassA and ClassB are static ones. The methods on these classes would need to be present on the interface. But then, in Java, one can't have an "abstract static" modifier
Can anyone suggest an elegant solution for this problem?
Well, there are a number of problems here. For starters, and this is the biggest one, this isn't going to work because you can't override static methods in Java. The goal, I think, of what you're saying is to be able to substitute, at run time, ClassA for ClassB or B or A or whatever, depending on some parameters. In order to do that, you need to be able to take advantage of dynamic dispatch (or, simply put, virtual methods) that would allow the runtime system to select the memory address of the method to be executed at run time. This isn't possible with static methods. You need to make the methods nonstatic for this to work. You don't have to specifically design a Java Interface but when you extend ClassA with ClassB, you'll be able to treat your objects as if they are simply a ClassA object.
All of that said, if you remove the static modifiers from the methods and make them nonstatic, then you could use ClassB in project A without having any import statements what-so-ever in the client class you're talking about. However, somewhere in project A, somebody is going to need to be aware of ClassB in order to instantiate it. That is, of course, unless you want to do some runtime binding stuff and load the class dynamically using a string. Does that make sense?
Firs problem: Your Class B and Class A's foo method is static. Hence nothing is being overriden. You should not make them static if you intend to override foo in ClassB.
The second problem here is that upstream needs to be aware of the downstream. That is just wrong isn't it?
The question of whether this is an abstract factor pattern or not is besides the point. Design patterns just make code follow a known structure. It is not an end in itself.
For now, why is it that your ClientClass in Project A needs to know about ClientB?
As for the factory, your factory needs to be in Project B and it can be something like:
class Factory {
public static ClassA createTheRightOne(EnvironmentSettings settings) { //do the right thing }
}
once you fix the static modifier
Pavan
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.
I have to implement a logic whereby given a child class, I need to access its parent class and all other child class of that parent class, if any. I did not find any API in Java Reflection which allows us to access all child classes of a parent class. Is there any way to do it?
For example:
class B extends class A
class C extends class A
Now using class B, I can find the superclass by calling getSuperClass(). But is there any way to find all the child classes once I have the parent class i.e. class B and class C??
If this wasn't homework (where 3rd party librares are probably not allowed), I would have suggested Google Reflections' Reflections#getSubTypesOf().
Set<Class<? extends A>> subTypes = reflections.getSubTypesOf(A.class);
You can do this less or more yourself by scanning the classpath yourself, starting with ClassLoader#getResources() wherein you pass "" as name.
You are correct: there is no direct API for this. I guess you could scan all loaded classes and see if they are a subclass of a given class.
One problem: you'll only able to find classes that are already loaded. None of these methods will find classes that haven't been loaded yet.
You can use:
thisObj.getClass().getSuperclass()
thisObj.getClass().getInterfaces()
thisObj.getClass().getGenericInterfaces()
thisObj.getClass().getGenericSuperclass()
I recently coded something to scan the members of a class and if those were non-primitives scan those as well. However, I did not traverse upwards so I didn't use the above methods but I believe they should do what you want.
EDIT:
I ran a simple test with the following:
public class CheckMe {
public CheckMe() {
}
}
public class CheckMeToo extends CheckMe {
public CheckMeToo() {
}
}
// In main
System.out.println( CheckMeToo.class.getSuperclass() );
// Output
class CheckMe
After that it's a matter of coding the traversal. If its parametrized then things may get a little complicated but still quite doable.
EDIT: Sorry didn't read carefully, let me look further into it.
EDIT: There doesn't seem to be any way to do it without scanning everything in your CLASSPATH and checking to make sure an object is an instance of some class.