I would like to use JAVA 8 default methods as a means for implementing multiple inheritance. So I have a repetitive code represented by the addValue() method that I need to move from the implementations to the interface.
interface IX {
ArrayList list = new ArrayList();
default void addValue(Object o) {
this.list.add(o);
}
}
class A implements IX {
//no addValue implementation here
}
class B implements IX {
//no addValue implementation here
}
class Main {
public static void main(String [] args) {
A a = new A();
B b = new B();
a.addValue(this);
b.addValue(this);
}
}
I would like to know
if this is a valid usage of default methods
If the a.addValue(this) syntax is correct
If two different list objects will be created
Java does not allow you to have multiple inheritance of state, only behavior.
If you want to share the declaration of an instance field you would need to place it in an abstract class.
if this is a valid usage of default methods
I use default methods heavily, but since I value immutability, i rarely place methods that mutate state in an interface.
Since (currently) all interface methods are public, if I need to inherit methods that mutate state I will place them (as protected) in abstract classes.
If the a.addValue(this) syntax is correct
No. Since you are in the static main method there is no "this".
What do you want to add to this list?
If two different list objects will be created
In your example only one (global) list will be created.
It is also important to note that ArrayList is not thread safe and in general should not be used in a global field, CopyOnWriteArrayList (or similar) should be used instead.
The example below:
/**
* The Interface IX.
*/
public static interface IX {
/**
* Gets the list.
*
* #return the list
*/
List<Object> getList();
/**
* Adds the value.
*
* #param o the o
*/
default void addValue(Object o) {
this.getList()
.add(o);
}
}
/**
* The Class AbstractIX.
*/
public static abstract class AbstractIx implements IX {
/** The list. */
protected List<Object> list = new ArrayList<>();
#Override
public List<Object> getList() {
return this.list;
}
}
/**
* The Class A.
*/
public static class A extends AbstractIx {
// no addValue implementation here
}
/**
* The Class B.
*/
public static class B extends AbstractIx {
// no addValue implementation here
}
/**
* The Class Main.
*/
public static class Main {
/**
* The main method.
*
* #param args the arguments
*/
public static void main(String[] args) {
A a = new A();
B b = new B();
a.addValue(1);
a.addValue(2);
b.addValue(1);
System.out.println("List a size should be 2: " + a.getList()
.size());
System.out.println("List b size should be 1: " + b.getList()
.size());
}
}
If two different list objects will be created
A single object is created
If the a.addValue(this) syntax is correct
No, try to add some string. The size of the list comes out to be 2
you can use sysout statements to figure such things out. :)
Thanks,
Amar
Related
/**
* Created by unibodydesignn on 11.03.2017.
*/
public interface Enumeration
{
// Returns true if another element in the collection exists
public boolean hasNext();
// Returns the next element in the collection as an Object
public Object getNext(); }
/**
* NameCollection implements a collection of names using
* a simple array.
*/
public class NameCollection
{
String[] names;
//this array will be initiliazed at outside
NameCollection(String[] names)
{
this.names = names;
}
/**
* getEnumeration should return an instance of a class that
implements
* the Enumeration interface where hasNext() and getNext()
* correspond to data stored within the names array.
*/
Enumeration getEnumeration ()
{
}
public boolean hasNext()
{
//i will define this method here
}
public Object getNext()
{
//i will define getNext() here
}
Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in
NamesCollection. Then write a main method that creates a NamesCollection
object with a sample array of strings, retrieves the Enumeration for this class via
getEnumeration(), and then iterates through the enumeration outputting each
name using the getNext() method.
I don't understand this question's concept. I clearly do not know what to do or where to start? Can I find Java's default hasNext() definition?
It is not homework.
It is a programming project from Absolute Java book. Chapter 13. P3.
Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in NamesCollection.
The purpose of the exercise seems to be working with anonymous classes.
For example, instead of creating a named class like this:
class NamesEnumeration implements Enumeration {
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
}
... the instructions guide you to use an anonymous class instead, like this:
Enumeration getEnumeration() {
return new Enumeration() {
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
};
}
An important point is that anonymous implementation can use variables visible in its scope. Most notably for this example,
the names field of the enclosing NamesCollection class.
In the NamesCollection class,
you don't need the hasNext and getNext methods.
So the class should look something like this:
public class NameCollection {
final String[] names;
NameCollection(String[] names) {
this.names = names.clone();
}
Enumeration getEnumeration() {
return new Enumeration() {
int currentIndex = 0;
// ^^^^^^^^^^^^ this is a hint for you
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
};
}
}
I've made some minor improvements, and added a hint to help you complete the implementation.
Lastly, the exercise also asks to add a main method to exercise this class. That should be something like this:
public static void main(String[] args) {
String[] sample = {"hello", "world"};
NameCollection namesCollection = new NameCollection(sample);
Enumeration names = namesCollection.getEnumeration();
while (names.hasNext()) {
System.out.println(names.getNext());
}
}
i dont know about that book you say, but lets understand what is requested:
What you need to do is create an implementation of the Enumeration Interface, i dont know if this chapter is about Interfaces, or Enumarations.
1: "Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in NamesCollection".
Here you need to return an implementation of the Enumeration interface, the question says to create an Anonymous class (but i sugest to create an Inner Class, maybe Private Inner Class). like this, inside the NameCollection class:
public Enumeration getEnumeration(){
Enumeration enumerat = new Enumeration(){
private int index = 0;
public boolean hasNext(){
return names.length > index;
}
public Object getNext(){
return names[index++];
}
};
return enumerat;
}
The method returns an implementation of the Enumeration class that you can use to traverse throught the array of names you passed to the constructor of the NameCollection class.
2: "Then write a main method that creates a NamesCollection object with a sample array of strings, retrieves the Enumeration for this class via getEnumeration(), and then iterates through the enumeration outputting each name using the getNext() method".
Here you just need to create a test class for your implementation:
public class Main {
public static void main(String[] args) {
NameCollection nc = new NameCollection(new String[]{ "Adriane", "Beatriz" });
Enumeration en = nc.getEnumeration();
while( en.hasNext() ){
System.out.printf("Name: %s \n", en.getNext() );
}
}
}
Im really trying to understand the importance of this interface, but beside helping us to write more quickly, the methods in the concrete classes (by only implementing the methods) I just can't find the need to use it.
The definition is this
an abstraction which declares the accept operation. This is the
entry point which enables an object to be "visited" by the visitor
object.
Each object from a collection should implement this abstraction in
order to be able to be visited
."
Its clear, but still you can manualy write those accept methods in every single class(which is lot of unnecessary work I agree) but still beside that you can get a class to be visitable, without the IVisitable interface...
//IVisitable.java
package Visitor;
/**
*
* #author dragan
*/
public interface IVisitable {
public void accept (Visitor v);
}
// Bgirl.java
public class Bgirl implements IVisitable{
int _br_godina;
public Bgirl(int g) {
br_godina = g;
}
public int getBr_godina() {
return _br_godina;
}
public void accept (Visitor v){
v.visit(this);
}
}
// Main.java
package Visitor;
/**
*
* #author dragan
*/
public class Main {
public static void main(String[] args) {
Bgirl terra = new Bgirl(5);
System.out.println(terra.getBr_godina());
VisitorImplement v = new VisitorImplement();
}
}
// VisitorImplement.java
package Visitor;
/**
*
* #author dragan
*/
public class VisitorImplement implements Visitor{
#Override
public void visit(Bgirl prva) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
prva._br_godina = 3;
}
// #Override
// public void visit(Bboy prvi) {
// // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
// System.out.println("BBOY VISIT");
//
// }
//
}
Look into your main() method: you can just directly call terra._br_godina = 3 and thus no need to use any visitor.
A visitor is useful when you don't know the concrete type of your terra and even don't know which method should be called to fullfil your wish. All you have is just an abstract type or interface e.g. Girl (or IVisitable). So, to demonstrate the usefulness of Visitor Pattern, your main() method should be like this:
public static void main(String[] args) {
IVisitable terra = new Bgirl(5);
// Want to set _br_godina of terra to 3 but do not and cannot know
// which method should be called
// Let's create a visitor and let him visit her,
// he knows how to set _br_godina of her to 3
VisitorImplement v = new VisitorImplement();
terra.accept(v); // luckily, every girl accepts the "accept()"
}
I'm new to Java and is trying to learn the concept of defining immutable objects. I have read in Java tutorial oracle that one of the ways to create immutable objects is
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
My question is, why not allowing subclasses to override methods can leads to creation of immutable objects? I'm struggling to understand the connection here.
Suppose String's methods could be extended by another class. There's no guarantee that the other class would be immutable like String is.
So if you call some library method and get a String back, will that String change or not? Is it the String base class or something that extended it that is mutable? String is a final class, so we don't have to worry about that.
I made an example of the confusion below:
public class WhyImmutableClassesShouldBeFinal {
/*
* This is an immutable class
*/
private static class ImmutableClass {
private final String data;
public ImmutableClass(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
/*
* This extends an immutable class, but is not immutable.
*/
private static class NotSoImmutableClass extends ImmutableClass {
private int oops;
public NotSoImmutableClass() {
super("WHATEVER");
}
public String getData() {
return Integer.toString(oops++);
}
}
/*
* Here's some function that looks like it returns an immutable class but
* doesn't.
*/
private static ImmutableClass immutableClassProducer() {
return new NotSoImmutableClass();
}
public static void main(String[] args) {
/*
* I called a method and got an ImmutableClass back.
*/
ImmutableClass c = immutableClassProducer();
/*
* But why is the value changing?
*/
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
}
}
ExecutorService and Service are interfaces and so only have abstract methods, which means that their methods are not implemented. How then can we call, e.g., future.get(), es.submit(), and es.shutdown() methods on references of the interface type? E.g., why can we do the following?
Future f = ...
f.get();
Here's a more concrete example:
import java.util.concurrent.*;
class Factorial implements Callable<Long> {
long n;
public Factorial(long n) {
this.n = n;
}
public Long call() throws Exception {
if (n <= 0) {
throw new Exception("for finding factorial, N should be > 0");
}
long fact = 1;
for(long longVal = 1; longVal <= n; longVal++) {
fact *= longVal;
}
return fact;
}
}
class CallableTest {
public static void main(String []args) throws Exception {
long N = 20;
Callable<Long> task = new Factorial(N);
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> future = es.submit(task);
System.out.printf("factorial of %d is %d", N, future.get());
es.shutdown();
}
}
This question got some downvotes because in one sense it's sort of basic, but I think it's actually sort of interesting. After all, a factory class like Executors in your example, can specify that it returns Executors. But, as you point out, that's just an interface, and you'd actually need an instance of something that implements Executor if you're going to be able to call those methods. Why doesn't the factory have to tell us the actual type of thing that's being returned?
If you haven't seen this before, it might not be clear how you could do such a thing. The important thing to remember is that if you have a class that implements an interface, then a method declared to return the interface type can return an instance of the class. That is, you can do:
interface Foo { /* ... */ }
class Bar implements Foo { /* ... */ }
class Factory {
Foo makeFoo() {
return new Bar( /*... */ );
}
}
makeFoo is declared to return a Foo, but Foo is an interface; you can't actually have instance of it. You can only have instance of classes that implement Foo. Bar does implement Foo, so you can return an instance of Bar.
The reason that we can do this is because when it comes time to invoke a method on an object, the implementation of the method is found in the actual object that we have a reference to. The way that methods are looked up is actually a bit complicated. Conceptually though, you might think of it like this: if you tell me that you're a Foo, then I can ask you to run any of the methods that are declared in Foo, but you get to decide exactly what you do for that method. I only get to use your Foo type in determining what methods I can ask you to execute. This is very important, and is why we can override methods in subclasses. These are called virtual methods. One of the reasons this is so important is that it enables us to use interfaces where we can reveal a minimal amount of information about our implementation (we can choose to say "I implement Foo, but that's all I'm telling you about myself), but still abide by a contract (i.e., I'm guaranteed to actually implement all the methods declared in Foo).
The following example is a bit more in depth, and captures a bit more of the factory pattern that you see with Executors.
Code
public class InterfacesExample {
/**
* An interface with one method.
*/
interface Frobber {
/**
* Frob the object.
* #param object the object
*/
void frob( Object object );
}
/**
* A factory class with one method for creating printing frobber.
*/
public static class Frobbers {
/**
* Returns a Frobber whose {#link Frobber#frob(Object)} method
* prints its argument
* #return a printing Frobber
*/
public static Frobber newPrintingFrobber() {
// This returns an instance of an anonymous class
// that implements the Frobber interface. It has
// to provide an implementation of frob(Object),
// though.
return new Frobber() {
#Override
public void frob( final Object object ) {
System.out.println( "Frobbing "+object+"..." );
}
};
}
/**
* Returns a Frobber whose {#link Frobber#frob(Object)} method
* prints the prefix and its argument
* #param prefix an object
* #return a prefixing printing Frobber
*/
public static Frobber newPrefixingPrintingFrobber( final Object prefix ) {
return new PrefixingPrintingFrobber( prefix );
}
/**
* A private, but not anonymous class. Instances shouldn't be
* made with its constructor, but rather through the factory
* method {#link Frobbers#newPrefixingPrintingFrobber(Object)}.
*/
private static class PrefixingPrintingFrobber implements Frobber {
final Object prefix;
public PrefixingPrintingFrobber( Object prefix ) {
this.prefix = prefix;
}
#Override
public void frob( final Object object ) {
System.out.println( "Frobbing "+prefix+":"+object+"..." );
}
}
}
/**
* Create some frobbers with the factory and test them out.
*/
public static void main( final String[] args ) {
final Frobber f1 = Frobbers.newPrintingFrobber();
f1.frob( 42 );
final Frobber f2 = Frobbers.newPrefixingPrintingFrobber( "boing" );
f2.frob( 36 );
}
}
Output
Frobbing 42...
Frobbing boing:36...
I've been given a class - GoodPetStoreClient - that makes use of another class - NoisyPetStore - in order to create a list of objects - Cat, Dog and Cow - which implement an interface - MakesSound - and have been asked to modify NoisyPetStore to ensure that GoodPetStoreClient will compile properly. I've been trying to work out what I'm missing, but without luck so far, and would appreciate some more experienced insight.
Thanks!
Here's the code
public class GoodPetStoreClient {
public static void main(String[] args) {
NoisyPetStore petStore = new NoisyPetStore();
petStore.addPet(new Cat());
petStore.addPet(new Cow());
System.out.println("I bought an animal, and it goes: " + petStore.buyNewestPet().makeNoise()); //moo...
System.out.println("The rest of the pet store goes: " + petStore.makeHugeNoise()); //meow
System.out.println("I bought another animal, and it goes: " + petStore.buyNewestPet().makeNoise()); //meow
petStore.addPet(new Dog());
System.out.println("The pet store now goes: " + petStore.buyNewestPet().makeNoise());
}
private static class CollisionInSpace {
// makes no sound at all
}
}
import java.util.ArrayList;
import java.util.List;
public class NoisyPetStore
{
//Stores pets
private List list;
public NoisyPetStore()
{
list = new ArrayList();
}
/* add a pet to the pet store after checking
* whether or not the object implements
* <MakesSound>
* #param o takes in a object of an unspecified
* class
**/
public void addPet(Object o )
{
//check if the instance implements the MakesSound interface
if(o instanceof MakesSound)
{
list.add(o);
}
}
/* get the last pet from the store by accessing
* the last item in the list, and hence the one
* which has been added most recently
**/
public Object buyNewestPet()
{
Object ans = null;
if (list.size() > 0)
{
ans = list.remove(list.size() - 1);
}
return ((MakesSound)ans);
}
/* creates a string representation of all of the noises
* made by pets which have been added to the list using
* a <StringBuilder>
* #return returns a String representation of all the noises
* made by the pets in the list
**/
public String makeHugeNoise() {
StringBuilder ans = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
ans.append(((MakesSound) list.get(i)).makeNoise());
}
return ans.toString();
}
}
public class Cat implements MakesSound
{
String sound;
/* Constructor for Cat object
* takes in no parameters and instantiates
* the instance variable sound
**/
public Cat()
{
sound = "Meeow";
}
/* Overrides the <makeNoise> method defined by the
* <MakeSounds> interface
* takes in no parameters and returns the sound made
* by a cat, represented as a <String> {#link String}
**/
#Override
public String makeNoise()
{
String s = sound;
return s;
}
}
//dog and cow have identical codes to cat, with the exception that they produce the sounds "Woof!" and "Moo!" respectively.
You can change this line:
public void addPet(Object o )
to this:
public void addPet(MakesSound aPet)
And this:
public Object buyNewestPet()
to this:
public MakesSound buyNewestPet()
This would enforce that you will only be able to pass objects that implement MakesSound interface to the addPet method. You won't need to use instanceof to verify this. Also buyNewestPet() will return objects that implement MakesSound interface, making the methods defined there available for invoking in GoodPetstoreClient.