What is a public interface? - java

"Using only the public interface of the linked list class, write a method
public static void reverse(LinkedList staff)
that reverses the entries in a linked list."
The part of all of that I'm not understanding is the first part. What does it mean by public interface of linked list class? Do I create a new class file that starts with something like public interface linkedlist? Can I add the method as a inner class within my main class?

The question is unnecessarily vague. What it's trying to ask is "using only the methods and fields of LinkedList that have the access modifier public, write this method."
You can put the method you write in any class you like, but the restriction says that you may only use public methods and fields on LinkedList to write it.
This also means that you can't create a subclass of LinkedList and use its protected methods.

The public interface of a class are its public properties (variables or fields you can read the values of or assign to) and methods (functions you can call).
So, the assignment is to create something that is not a subclass of LinkedList. Creating a subclass would give you access to protected methods for example. You need to create something external to LinkedList, for example:
void MyMethod()
{
LinkedList l = new LinkedList();
// do something with l here.
}

"Public interface of linked list class" means only public methods of the LinkedList class. See the javadoc, there is a list of all public methods, or create new LinkedList instance and let your IDE suggest.

Related

getting child class from static method of parent class in Java

Suppose I have these classes:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
Lets say when calling ParentClass.printClass() I want to print the name of the class (like doing System.out.println(ParentClass.class)). When then extending ParentClass (for example like in ChildClass) and calling ChildClass.printClass(), I want it to print the name of the extending class (like doing System.out.println(ChildClass.class)). Is this somehow possible?
I've found a way to get the class from inside a static method by using MethodHandles.lookup().lookupClass(), but when using it inside of ParentClass.printClass and extending ParentClass, then calling printClass on the extending Class, I always get the class of ParentClass.
static methods are best thought of as living entirely outside of the class itself. The reason they do show up in classes is because of the design of java (the language) itself: Types aren't just types with a hierarchy, they also serve as the primary vehicle for java's namespacing system.
Types live in packages, packages are the top level namespace concept for types. So how do you refer to a method? There's only one way: Via the type system. Hence, static methods do have to be placed inside a type. But that's about where it ends.
They do not inherit, at all. When you write:
ChildClass.lookupClass()
The compiler just figures out: Right, well, you are clearly referring to the lookupClass() method in ParentClass so that is what I will compile. You can see this in action yourself by running javap -c -p MyExample. The same principle applies to non-static methods, even.
For instance methods, the runtime undoes this maneuvre: Whenever you invoke a method on any object, the runtime system will always perform dynamic dispatch; you can't opt out of this. You may write:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
Quoting #RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.

Relationship between class and iterator interface

Will a class become an iterator object itself if it implements an iterator interface.
For example,
public class StringGridIterator implements Iterator<String>{
//some methods here...
}
or Do I need to specifically create a variable reference to an iterator object that will iterate through a certain String objects?
like this...
Iterator<String> it = object.iterator();
I don't know if this is clear enough for you to understand since I am still struggling with understanding Java concept like class and object myself.. Just leave a comment if you don't understand what I am trying to say.
A class will not become an Iterator object by implementation. You may be thinking of extending a class. (See: What's the difference between the implements & extends keywords in Java).
From your examples, it looks like you are attempting to do 2 different things: class inheritance vs. an iterator object. The .iterator() method returns an Iterator containing the elements of your object.

Creating custom Iterator Java?

I'm a bit confused about how to implement a custom iterator for a class in Java. I'm required to essentially make an ArrayList without using the inbuilt libraries already available to me. I understand the basics of creating the class but I'm having trouble understanding how to get the Iterator to fit into all of this. I have the following:
I have created a generic class that implements the iterable interface as such it looks something like this:
public class MyArrayList<T> implements Iterable<T> {
I've then got to create a class called MyIterator which according to the wording of the document is a stand alone class. This seems fairly straight forward I make a new class called MyIterator and have it implement the iterator interface so it looks something like this:
public class MyIterator<T> implements Iterator<T>{
My confusion lies in the following. The document says that the Iterator needs to be in it's own class, but how then do I access the data members in "MyArrayList" to fully implement hasNext() and next() for example. As the data members in the underlying array are private (as they should be) I don't see how an external class can fully implement these methods. Am I misunderstanding what is required? By separate class is it still a part of the "MyArrayList" class but defined differently?
I hope that helps, as I said I think I understand what is required of me I just am not exactly sure where my Iterator fits into all of this.
While the iterator has to be a separate class *, that class will probably have some relation to your Iterable class.
It's often a nested/inner class, precisely because it needs to access the values of the class (and that's what pretty much what inner classes are made for).
Granted, if the Iterable is a List you could implement an Iterator without any "internal" access at all, but you usually still want to get access to the internals for things like checking the modCount (to throw a ConcurrentModificationException when the Iterable is structurally modified while you iterate over it ... and to prevent that exception if you modify it via the Iterator itself).
* you could implement it with your Iterable instance itself, but that would break the contract as soon as the user uses two iterators at the same time.
You have to declare your own methods hasNext(), next(), remove(). It has to know how to iterate over your own class, how to go to next element and how to check whether next element exists.

Java method that accepts references to interface objects

I'm kinda unsure about the following question:
If Launchable is a Java interface, what objects can be passed into the following method? What methods could be invoked on item inside this method?
public void prepareForLaunch (Launchable item) {
// some code
}
My current answer is:
From the above information, the only objects that can be passed into the method are objects that where instantiated as subclass types of the interface Launchable.(?) The methods that could be invoked on item inside the method would have to be public methods or protected methods within the same package. These methods would also have to be to be intended for a subclass of Launchable object since it is only in abstract and actual(concrete) classes where a method body’s definition can exist.
I was wondering if someone here can check my answer and add any suggestions. Thanks!
You can only pass in instances of classes that implement Launchable (either directly, or by inheritance from a superclass). You can also pass in null.
Inside of the method, you can call all the methods defined in Launchable (and in Object).
These methods would be defined in the Launchable interface, but implemented in the actual class (a fact that is guaranteed by the Java type system, which won't let you have classes with incomplete interface implementations, those would need to be declared abstract and cannot be instantiated).
If you need to call any other methods you need to know that the object in question also implements some other interface (or is of a given class), and do a typecast to that first.
Since you stated that Launchable is an interface, an instance of any class that implements Launchable could be passed to prepareForLaunch. Any class implementing Launchable would have to implement the methods defined in the interface and thus any method of Launchablecould be invoked to objects given to prepareForLaunch.
You are right about the first part. About the methods you can invoke: If you are not using casting then you can only invoke public\protected within the same package of Launchable. If you will use casting you can extend the range of the methods you can invoke to the methods in the casted-to class.
Consider this code:
public interface Launchable
{
public void aMethod();
}
public class SomeClass implements Launchable
{
public void aMethod()
{
}
public void bMethod(){}
}
Without casting youll be able to call
item.aMethod();
With Casting youll be able to call:
((SomeClass)item).bMethod();
you should use implements statement ,
public void prepareForLaunch() implements Launchbla {
}

Java: Deriving from a generic List/Collection

I have a little problem understanding the Java language
public class PhonebookEntryList extends List<PhonebookEntry>
{
public PhonebookEntryList(String filename) throws IOException
{
//loadListFromFilename(filename);
}
public void saveListToFilename(String filename) throws IOException
{
//Do something to save it to a file
}
}
I can't do this, because List is a generic Type (of course). I know what that means, but at the moment I can't think of a Solution for this problem.
Can you help me to solve it? Thanx!
No, your only problem is that you're extending an interface; you must implement it instead.
public class PhonebookEntryList implements List<PhonebookEntry>
should work; or you might prefer to extend a concrete class:
public class PhonebookEntryList extends ArrayList<PhonebookEntry>
or
public class PhonebookEntryList extends LinkedList<PhonebookEntry>
You can't do that because List is an interface. But!
You shouldn't extend or implement a List class to make a PhonebookEntryList, it's a design error.
You should do:
public class PhonebookEntryList
{
private List<PhonebookEntry> entries;
public PhonebookEntryList(String filename) throws IOException
{
//loadListFromFilename(filename);
}
public void saveListToFilename(String filename) throws IOException
{
//Do something to save it to a file
}
}
I.e. your PhonebookEntryList should contain a list instead of inheriting it.
List<T> is an interface, not a class, so you can't inherit from it. You can, however, inherit from a generic type, supplying the type argument, if you wish to create, e.g. a collection for a specific type with some behaviour specific only to that type.
Your Problem is that you are trying to extend an interface rather than implement it.
Composition is what you want. Create a class that wrapps a List (or something that iplements that interface)
and add functionality.
Should I mention that List is an Interface and not a Class? Nah. I think you got the point by now.
I would like to point out, however, that it's usually better NOT to embed the persistence mechanism within the list class. There's this thing called the Visitor pattern that works better. By placing the actual persistency code in a seperate class, the overall logical complexity of the app gets reduced (at the expense of an extra class), and your phonebook becomes liberated to be used in places where having dependencies on the persistency mechanism that looked good when you first designed the code don't look so good anymore. For example, if you wanted to make the Phonebook be an item in an ORM-referenced database.
List<T> is an interface.
If you want to extend a class you'll have to choose an implementation (ArrayList<T> maybe): extends ArrayList<PhonebookEntry>
If you want to implement a List change your code to: implements List<PhonebookEntry>
If you look at the JavaDoc for List, you'll see (as others mentioned) that it's an interface, not a class. What you most likely want to do is look on the same JavaDoc page at "All Known Implementing Classes" and you'll see AbstractList. Extend this. Alternatively, extend one of the non-abstract List implementations.
Note: Most of the time when someone starts to extend one of the Java Collection classes, you're going down the wrong route. Usually, it's better to use one of the existing collections in your class and proxy any collections-style requests that you need. Or return an unmodifiable proxy of your collection:
public class MyClass {
private final List<PhonebookEntry> myList = new LinkedList<PhonebookEntry>();
public List<PhonebookEntry> getList() {
return Collections.unmodifiableList(myList);
}
}
Usually, it's best to extend a class only if you intend to have different behavior than the class you are extending. Inheritance is more brittle than composition.

Categories