How to use same inner class in different List classes? - java

I am working on a problem where I implement different Linked lists. All the list classes include two inner classes; a Node-class and an Iterator-class.
These inner classes are entirely identical to each other. In the Iterator-class, some of the methods rely on accessing information from the outer class, which works fine. Is there a way to do this in java, so that I would not need to include the very same code in all my different list-classes? I feel clueless - I just don't know where to look.
This is what my Node-class looks like:
class Node{
Node next;
Node previous;
private T data;
Node(T inn){
data = inn;
}
public Node getNesteNode(){
return next;
}
public T getData(){
return data;
}
}
Edit: I realize the Node class is relying entirely on itself.
Here is my simple Iterator:
class LenkeListeIterator implements Iterator<T>{
private int field = 0;
Node denne = forste;
#Override
public boolean hasNext() {
return field!= storrelse();
}
#Override
public T next() {
T data = denne.getData();
denne = denne.getNesteNode();
field++;
return data;
}
}

By definition, an inner class is an intrinsic part of the class containing it. It can only be shared with subclasses, not peers or classes outside the hierarchy of the parent class entirely.
There's nothing in your Node class that requires it to be an inner class, so you could just make it standalone. But if there were something that made it need to be an inner class, you could put all the parts that don't into a standalone class that is then subclassed in each of the parent classes to provide it with access to the parent's inner data.
E.g. (roughly):
abstract class Example {
protected int something;
public void logic() {
SomeType data = this.getParentData();
/* ...do something with `data`... */
}
abstract protected SomeType getParentData();
}
Then an inner class in, say, Container would subclass it and provide getParentData.
class Container {
private SomeType data;
class ContainerExample extends Example {
protected SomeType getParentData() {
return data;
}
}
}

Related

How do you hide a class behind an interface when that class contains a package-level method?

How do you hide the following class behind an interface (and instantiate it using a factory)?:
public class TreeNode {
private List<TreeNode> children;
private TreeNode parent;
public void addChild(TreeNode newChild) {
children.add(newChild);
newChild.setParent(this);
}
public TreeNode getParent() {
return parent;
}
public void removeChild(TreeNode child) {
children.remove(child);
child.setParent(null);
}
void setParent(TreeNode newParent) {
if(parent != null) {
parent.removeChild(this);
}
parent = newParent;
}
}
Suppose you were to rename the class to TreeNodeObj and have it implement the TreeNode interface:
class TreeNodeObj implements TreeNode {
private List<TreeNode> children;
private TreeNode parent;
public void addChild(TreeNode newChild) {
children.add(newChild);
newChild.setParent(this);
}
... etc. ...
}
public interface TreeNode {
public void addChild(TreeNode newChild);
public void removeChild(TreeNode child);
public TreeNode getParent();
}
public class NodeFactory {
public static TreeNode createTreeNode() {
return new TreeNodeObj();
}
}
This code doesn’t compile, because setParent() isn’t defined in the TreeNode interface (since it should not be called directly and should not be exposed outside the package).
The only solution I can think of is to make the following modification:
public interface TreeNode extends TreeNodePackageAccess {
public void addChild(TreeNode newChild);
public void removeChild(TreeNode child);
public TreeNode getParent();
}
interface TreeNodePackageAccess {
void setParent(TreeNode newParent);
}
class TreeNodeObj implements TreeNode {
…[previous code]…
public void setParent(TreeNode newParent) {
// this method is made public in order to implement TreeNodePackageAccess
…[previous code]…
}
}
Is there a better way to accomplish this than with the above strategy? (Also, with the above strategy, setParent() is still accessible from outside the package via reflection, so technically, you don't even get package-level encapsulation with it.)
How do you hide the original class behind an interface, given that it requires a package-level method that shouldn’t be exposed?
Just cast it to the implementation class where needed. If any implementation of TreeNode is not a TreeNodeObj, throw an exception that indicates it came from an invalid provider.
Java SE already does this. From the documentation of the java.nio.file package:
Unless otherwise noted, invoking a method of any class or interface in this package created by one provider with a parameter that is an object created by another provider, will throw ProviderMismatchException.
So your other classes in that package can do things like:
#Override
public void add(TreeNode node) {
if (!(node instanceof TreeNodeObj)) {
throw new WrongProviderException(
"Argument was created by a different provider: " + node);
}
TreeNodeObj obj = (TreeNodeObj) node;
obj.setParent(parent);
}
How do you hide a class behind an interface when that class contains a package-level method?
As posed, there's nothing special required here. You can abstract any number, including zero, of a class's public methods with an interface. It is not necessary in any general sense that all methods of the class be mirrored as abstract methods of the interface.
But you seem to mean that you want to represent one or more package-access methods in an interface, and this is not possible. Interface methods may be only public or private, and private methods are not abstract. The implementation of an abstract method cannot narrow its access, so the implementation of an abstract interface method must be public.
Your idea to split the interface into a package-access superinterface and a public subinterface does not help in any way, even if you were willing to make the implementation method public after all. Any method declared by the superinterface is inherited by the subinterface and can be accessed through it.

Changing visibility of method in inherited class

I've got two class: GraphNode and BTNode extends GraphNode. I've got method:
public GraphNode.addChild(GraphNode node)
as GraphNode may have many children
and two methods:
public BTNode.addLeftChild(BTNode left)
public BTNode.addRightChild(BTNode right)
as BTNode may have only two children
How may I restrict public access to inherited addChild(GraphNode node) method from BTNode class? I wouldn't like to have that publicly accessible from that level (while remaining public access from GraphNode class)?
If you extend (or implement) from a class (or interface) then the parent will specify the whole signature of a method. There is nothing you can change about it, you will always need to have the method public if your parent specifies it as public.
Otherwise you would run into problems when casting like ((Parent) child).theMethod(). The object itself is child but the view gets reduced to the Parent class. The method gets invoked from the child class, so it would be private although you casted it to Parent which specified it as public.
However you could do something like:
public class Child extends Parent {
#Override
public void theMethod() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
private void otherMethod {
// Do something
}
}
But note that saying "I am extending class XY but not supporting all of its methods" is not the best design. It is a sign that the parent class (or other parts of the architecture) could have been structured more modular in the first place.
It is not possible to reduce the visibility of a method in subclass. The subclass need to be a valid instance of the base class.
As you can see in the previous answers, it is not possible to change visibility of public methods in the child classes. But in case of you are designer of GraphNode class, you could use a little bit another class hierarchy:
public abstract class BaseNode {
protected final Map<String, GraphNode> children = new HashMap<>();
protected void addChild(String id, GraphNode node) {
children.put(id, node);
}
}
public class GraphNode extends BaseNode {
public void addChild(GraphNode node) {
children.put(String.valueOf(System.currentTimeMillis()), node);
}
}
public class BTNode extends BaseNode {
private static final String LEFT = "left";
private static final String RIGHT = "right";
public void addLeftChild(BTNode node) {
addChild(LEFT, node);
}
public void addRightChild(BTNode node) {
addChild(RIGHT, node);
}
}

Create a parent class that returns child class objects

I'm building a base/parent class in Java that's going to have several methods for creating the class itself and I'm wondering if there's any way to have the parent class return instances of the child class instead of returning instances of the parent class that then have to be cast to the child?
For example, here's my parent class:
public abstract class SFObject
{
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<SFObject> CreateListFromQuery(Connection connection, String query)
{
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
If I create a child class based on my SFObject class, the two functions in my child class will still return an SFObject (that needs to be cast to my child class type) or a list of SFObjects (that need to be individually cast to my child class type). Is there any way (maybe using Reflections) to have my child class returns instances of itself as itself and not as SFObjects?
What you are describing is known as a covariant return type.
Class A {
A getInstance() { ... }
}
Class B extends A {
#Override
B getInstance() { ... }
}
This has been allowed since Java 1.5.
If you place the child class object inside of the parent object, methods called will run from the child class. But it will look like the parent object on the surface
public class A{
method 1(){//do some stuff}
method 2(){//do some stuff}
}
public class B extends A{
method 1(){super.method 1()
//do some other stuff}
method 2(){super.method 2()
//do some other stuff}
}
public class test{
A a = new B();
//any method called on 'a' will come from the child class
// But 'a' is the parent object
}
Not sure if I really understand your Problem correct because it sounds to me lke this:
class p
{
public static p createParent()
{
return new p();
}
public static c createChild()
{
return new c();
}
}
Of course it doesn't have to be static, just thought of some kind of factory.
Exactly for this functionalities are proposed the factory methods, as you already implemented. In the child class you can change the return type without offending the method declaration. A sample for your case would be something like:
public abstract class SFObject {
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<? extends SFObject> CreateListFromQuery(Connection connection, String query) {
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
class SFObjectChild extends SFObject {
#Override
public SFObjectChild CreateFromDiffObject(DiffObject object) {
SFObjectChild result = new SFObjectChild();
//...
return result;
}
#Override
public List<? extends SFObjectChild> CreateListFromQuery(Connection connection,
String query) {
return null;//..;
}
}
This is acceptable because the return type of the children class is still a kind of (hierarchical speaking) the parent.
Be aware of java code conventions (methods in camel case starting with low, e.g. createFromDiffObject).

Java - polymorphism with collection attributes

I would like to ask if there is a more elegant way to write the following code:
public class MTree {
class MTreeObject {
double[] vector;
}
class RoutingObject extends MTreeObject {
double radius;
}
class LeafObject extends MTreeObject {
int id;
}
class Node {
LinkedList<MTreeObject> list;
}
class InnerNode extends Node {
LinkedList<RoutingObject> list;
}
class LeafNode extends Node {
LinkedList<LeafObject> list;
}
public static void main(String[] argv) {
MTreeObject object = new RoutingObject();
Node node = new InnerNode();
((InnerNode)node).list.add((RoutingObject)object);
}
}
the problem is that if I have for example:
class Result {
Node node;
}
and then call in main
public static void main(String[] argv) {
Result result = new Result();
MTreeObject object = new RoutingObject();
result.node = new InnerNode();
result.((InnerNode)node).list.add((RoutingObject)object);
}
it doesn't work the way I want. Well I could also do:
newnode = result.node
((InnerNode)newnode).list.add((RoutingObject)object);
but then I would have too much variables in my more complex code...
The problem is you have declared all your classes as inner classes of MTree. An instance of your inner classes can exist only within an instance of the outer class (MTree).
Try making your classes (RoutingObject, LeafObject, etc.) stand alone classes rather than nested or
to instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
MTree mtree = new MTree();
MTree.Node node = mtree.new Node();
See: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Not quite sure from your example what you are trying to accomplish, my guess best guess is you should just not use nested classes. Hope this helps.

Usage of inner class

I can understand what inner class is and how to write program. My question is in what situation do programmers really need inner class?
Sometimes there is some functionality which is best represented as an object, but which is only meaningful within the context of another object, which does not necessarily need to be exposed to the outside world, and which can benefit from having access to the parent classes data (so as to not violate encapsulation).
The best example that I can think of is putting a Node class inside of a LinkedList. Nodes are only meaningful to the LinkedList, so they only exist within one. No one outside of the LinkedList cares about nodes or should have access to them.
An inner class allows us to remove that logic and place it into its own class. So from an object-oriented point of view, we've taken functionality out of where it doesn't belong and have put it into its own class.
Please go through this link....
http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html
Also as you know in Java exists nested classes, which is static inner clasess.
From previous posts becomes clear when we need to use an inner class but I think you also interested in the question "Why we need nested classes (static inner class)".
The answer is simply, there is the same purpose as for the inner class except few things.
1) The nested class (static inner) is required when we whant to exclude some logic that concerns another object but this logic might be used in outworld.
The simpliest examples is a builders or editors of some object. For example we have class Foo
which may have a lot of optional fields, to construct such object we may decide to introduce a builder class which will do this work.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
This example illustrates at leas one reason why we need such classes
2) The second difference between inner and static inner classes is that the first one always has pointer to the parent class. Actully compiler creates synthetic field member for the non static inner class of the type of it's parent, exectly of this reason we can access private members of the parent class. The static inner clasess doesn't has such generated field member. For instance we has just simple parent class with declared non static inner class:
public class Foo {
public class FooBuilder {
}
}
but in fact if take into account the byte code it looks like:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
if you want you can figure out this throught generated byte code.
One of the use of inner class is :
Inner class helps in multiple-inheritance. Inner class allows you to inherit from more than one non-interface.
//first case; can implement if two classes are interface
interface A { }
interface B { }
class X implements A, B { }
//second case; you can extend only one class. This case inner class can help to inherit other class as well
class D { }
abstract class E { }
class Z extends D {
void method() {
return new E() { }; //Anonymous inner class
}
}
When you want to specify a class that has sence only in context with the bounded one.
For example you write a MathOperations class that can execute four operations. So the operations can be represented as inner enum MathOps.
When the inner class is not used anywhere except the inbounded one.
You use anonymous inner classes to specify only the operation, for exmple if you want to sort a collection, you specify a Comparable class just for one method compare.
Collections.sort(employments, new Comparator<Employment>() {
#Override
public int compare(Employment o1, Employment o2) {
return o1.getStartDate().before(o2.getStartDate()) ? 1 : -1 ;
}
});
With inner classes you can access private members of the enclosing class.
They are useful for interface implementations that are only used by the enclosing class (event handlers in a application).
They are useful for providing fine grained access and creation control over an interface implementation that is retrieved externally (maybe something like an Iterator implementation).

Categories