I need little help here. I have three classes Book, Member, Bean.
Book.java
public class Book
{
public Member m=null;
// various getter & setter methods
}
Member.java
public class Member
{
public Book b=null;
// various getter & setter methods
}
In Bean.java I create an object of Book class & through this object we have to access all methods of Book as well as Member class.Now the problem is the object of Member class created in Book is not initialized & we can't use new operator to initialize it & we can't make it static. If we use new operator the result is not come.
This design is not correct.
There is a circular dependency.
Book has a Member and Member has a Book .
You need to double check this design.
Constructor injection would be the easiest way to fix this once you have the dependencies sorted out.
UPDATE : Corrected design which I feel is correct.
//Book
public class Book {
private String bookName;
private String authorName;
//getters and setters
}
//Member will have a book (maybe multiple) associated with them
public class Member {
private Book[] bookArray;
public Member (Book... books) {
this.bookArray = books;
}
}
Related
I have a Pojo named A and another Pojo named B which extends A:
public class A
{
private String name;
//constructor, setter and getter comes here.
}
public class B extends A
{
private long id;
//constructor, setter and getter comes here.
}
i have an instance of class A with a name.
A a = new A();
a.setName("udy");
I would like to get an instance of class B with all the values of a but without knowing what are the fields and values in a
Copy constructor wouldn't do the trick since when adding a field to A, i must update the copy constructor of B
Dozer can do the trick, but i would like to avoid creating a copy.
i did some search but didn't find what i was looking for.
Any suggestion would be really appreciated!
This was an interview question. The interviewer presented me a class Person and another Class Community. He wanted to know what can we do to make sure that within the Class Community, the instance of the Class Person can be called once.
My approach was to define a boolean flag as a Global variable and to check in the constructor of Class Person if the flag value was false, then it will create the instance or else return error. This flag value is changed to true with the creation of the first instance of Class Person.He did not seem very satisfied with the answer.
I understand that this may be not the right way of doing this. Question is, is there a way to do so using Class definition,or a specific type of class?
I'm not really sur about all the Singleton proposition.
I would have answered the same. But the real question seems to be "How to make the person unique within a community" which is different from "How to make sur we can instanciate Person class once for all".
In that case, I would have done something really different.
I would declare a Set of Person within Community and override Person's equals method.
Then, within a community, the Person would have been unique but Person class could still be instanciated for other Community instances.
public class Person{
...
public Boolean equals(Object o){
Person p = (Person) o;
//you own equals logic
return isEqual;
}
...
}
public class Community{
...
private Set<Person>;
...
}
You'd use the Singleton Pattern.
public class Singleton {
// Private constructor. Prevents instantiation from other classes.
private Singleton() { }
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Or create your class as an enum type, making it a true singleton:
public enum Singleton {
INSTANCE;
public void execute (String arg) {
// Perform operation here
}
}
I am fairly new to the concept of abstract data types an was looking for clarification because I could not find any good examples online.
From my understanding, the sub class inherits all methods and variables from the abstract but I think I am misunderstanding this. For example, I am creating a menu using the abstract data type MenuItem
import javax.swing.*;
public abstract class MenuItem{
private String itemName;
private int ct;
private double costPer;
public String getItemName()
{
return itemName;
}
public int getCt()
{
return ct;
}
public double getCostPer()
{
return costPer;
}
}
public class Hamburger extends MenuItem{
itemName = "Hamburger";
ct = 0;
costPer = 4.99;
}
I know this is incorrect but can someone tell me why? Does the subclass hamburger only inherit the methods or what?
There are several issues:
itemName et al are private, so even though they're inherited, they're not visible to the subclass.
The syntax you use in Hamburger is invalid.
Here is how you could fix your code:
public abstract class MenuItem{
public MenuItem(String itemName, int ct, double costPer) {
this.itemName = itemName;
this.ct = ct;
this.costPer = costPer;
}
...
}
public class Hamburger extends MenuItem{
public Hamburger() {
super("Hamburger", 0, 4.99)
}
}
Finally, I'd say that instead of using an abstract base class and a bunch of concrete classes, it would be better to use a single concrete class for MenuItem and make Hamburger etc instances of that class.
The problem lies in the visibility of the fields in your MenuItem parent class. private visibility means, that they are not visible to any other class including own subclasses.
In oreder to make your fileds visible to subclasses, you have to change their visibility to protected. Be aware that this makes the fields visible to all classes in the same package as well.
All the memeber visibility issues are covered in greater detail in this article
From my understanding, the sub class inherits all methods and variables from the abstract but I think I am misunderstanding this
yes, your understanding about your mis-understanding is correct. :-)
sub classes in java do not inherit the private member variables. they get public and protected members only.
itemName, costPer and ct are declared as private access fields. They are only accessible from within the class they are defined in. If you declare them with protected access, you'll be able to access them.
As defined in the Java Language Specification, section 6.6 Access Control
A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:
...
(Otherwise,) if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
...
Before you start looking into abstract types, start with the concept of encapsulation, and try to understand it as it is considered (by many) as the most important concept in the object-oriented design, followed by polymorphism, and inheritance. If class members are private, no subclass will be able to access them directly.
Yes, Hamburger only inherits the methods. That's because they're public. If you made them private (like the fields) they wouldn't be inherited either. Here's how to fix the problems.
import javax.swing.*;
public abstract class MenuItem {
//To be visible to subclasses, these need to be public, package-private, or protected
protected String itemName;
protected int ct;
protected double costPer;
public String getItemName() {
return itemName;
}
public int getCt() {
return ct;
}
public double getCostPer() {
return costPer;
}
}
public class Hamburger extends MenuItem {
//These assignments need to be inside a block, like a constructor
public Hamburger() {
itemName = "Hamburger";
ct = 0;
costPer = 4.99;
}
}
An abstract class can never be instantiated. Its sole purpose is to be extended. In an abstract class, if you specify atleast one method as abstract, then the whole class needs to be specified as abstract. An abstract class allows you to have implemented and unimplemented (abstract) methods all in the same class. If all methods in the class are abstract, then you effectively have a interface, and any variables declared in an interface are treated as constants. The variables in your question are not inherited as they are private to the abstract class. You must access them through the methods of the abstract class.
What are some alternatives to inheritance?
Effective Java: Favor composition over inheritance. (This actually comes from Gang of Four, as well).
The case he makes is that inheritance can cause a lot of unseemly side effects, if the extended class was not explicitly designed to be inherited. For example, any calls to super.someMethod() can lead you through unexpected paths of unknown code.
Instead, hold a reference to the class you would have otherwise extended, and delegate to it.
Here is a link to an interview with Erich Gamma where he talks about the concept a bit.
Some alternatives:
Delegation, also known as Composition
Wikipedia article on limitations and alternatives to inheritance
Q:Inheritance seems error-prone. How can I guard against these errors? And, what are the alternatives?
I'm assuming you're playing with Java which has some rules about inheritance.
Implementing interfaces is a common and oft used option. So, for example, if you have a data-source class that talks to a RDBMS, rather than inheriting that class and using it to implement a NoSQL datasource, the both can implement the same interface.
Rather than..
public class RDBMSDataSource {
...
public String loadSomeDataFromDataSource() {
...Do some stuff...
}
}
public class NoSQLDataSource extends RDBMSDataSource {
...
#Override
public String loadSomeDataFromDataSource() {
...Do some other stuff...
}
}
public class DataSourceClient {
public void foo() {
RDBMSDataSource ds = new NoSQLDataSource();
ds.loadSomeDataFromDataSource();
}
}
Which works but is hard to read, you could use this...
public interface DataSource {
public String loadSomeDataFromDataSource();
}
public class RDBMSDataSource implements DataSource {
...
public String loadSomeDataFromDataSource() {
...Do some stuff...
}
}
public class NoSQLDataSource implements DataSource {
...
#Override
public String loadSomeDataFromDataSource() {
...Do some other stuff...
}
}
public class DataSourceClient {
public void foo() {
DataSource ds = new NoSQLDataSource();
ds.loadSomeDataFromDataSource();
}
}
Another option would be composition. Say you have employees and customers. Your two options would be...
public class Person {
protected String name;
protected String address;
...More stuff...
}
public class Employee extends Person {
protected String jobCode;
protected String department;
...More stuff...
}
public class Customer extends Person {
protected String salesPerson;
protected Date registrationDate;
...More stuff...
}
...or...
public class ContactInfo {
private String name;
private String address;
...More stuff...
}
public class Employee {
private ContactInfo contactInfo;
private String jobCode;
private String department;
...More stuff...
}
public class Customer {
private ContactInfo contactInfo;
private String salesPerson;
private Date registrationDate;
...More stuff...
}
Since Java does not have multiple inheritance and you can implement multiple interfaces, you sometimes need to do the above to make sure your development is clean and readable.
I realise this is not Java per se, but Scala (a language running on the Java Virtual Machine) permits mixins (known as traits in Scala).
Mixins allow you to slot some functionality alongside an existing class, rather than within the inheritance tree.
When a class includes a mixin, the
class implements the interface and
includes, rather than inherits, all
the mixin's attributes and methods.
They become part of the class during
compilation
Delegation is an alternative to inheritance.
I think you should try delegation, delegation is an alternative to inheritance. Delegation means that you include an instance of another class as an instance variable. and it plays a beneficial role that it doesn't force you to accept all the methods of the super class.
Try Delegation which is also know as Composition
Also found the new alternative as mixin
The mixins are kind of composable abstract classes. They are used in a multi-inheritance context to add services to a class. The multi-inheritance is used to compose your class with as many mixins as you want. For example, if you have a class to represent houses, you can create your house from this class and extend it by inheriting from classes like Garage and Garden. Here is this example written in Scala:
val myHouse = new House with Garage with Garden
You will get more info about mixin https://kerflyn.wordpress.com/2012/07/09/java-8-now-you-have-mixins/
Why do we need constructors and private members in the abstract class? It is not like we are ever going to create an instance of that class.
You will create instances, just instances of a derived class. Those derived classes will still need to call constructors, and can still call members of the abstract class - which may in turn use private members.
Here's an example (not a terribly useful one, but just to show the basic idea...)
public abstract class NamedObject
{
private final String name = name;
protected NamedObject(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
public class Computer extends NamedObject
{
private final int processorSpeed;
public Computer(String name, int processorSpeed)
{
super(name); // See, the constructor is useful
this.processorSpeed = processorSpeed;
}
public String toString()
{
return getName() + " (" + processorSpeed + ")";
}
}
I can't say I write abstract classes that often, generally preferring composition to inheritance, but when I do create them I certainly use constructors and private members.
Abstract classes provide a partial implementation of some interface. It's perfectly reasonable to consider that you might want to provide part of that implementation and disallow client code (concrete subclasses) from accessing the specifics - i.e. an extension of the principle of encapsulation.
Marking some members as private forces the inheriting class to call protected methods to access that partial implementation; providing a constructor allows for subclasses to initialise the parent's encapsulated state during their own construction.
Unlike an interface, an abstract class that defines data fields is in fact instantiated in the sense that these data fields are allocated. It is just that they are never instantiated on their own, they are instantiated as part of something bigger - the subclass. So when the subclass is built, the supertype is built as well, which is why you would need a constructor.
Depending on your hierarchy, your abstract class may have a meaning and state. For example, if your application is a school you may have the notion of a person (that has a name and an SSN), but you would have different subtypes for students and for faculty. Because both types of people share certain state structure (name and SSN) you would have both classes extend the Person class. But you would never simply instantiate a person directly.
In addition to Jon's answer, I'd like to mention that abstract classes still go well with composition, if you keep the subclass tree shallow. I.e. it is great for providing a common base class for a few closely related objects, but not for creating a gigantic tree of subclasses.
Why do you need private class? I think that you are confusing abstract classes with interfaces. Unlike interfaces, abstract classes can hold functionality. For example:
public class AbstractBase{
private int num;
public AbstractBase(int number){
this->num = number;
}
public int method(){
return ( this->num * this->templateMethod());
}
public abstract int templateMethod();
}
public class ConcreteDerived extends AbstractBase{
public ConcreteDerived(){
super(4);
}
public int templateMethod(){
return number; //number is the result of some calculation
}
}
In this example, you´ll never explicitly instantiate AbstractBase, but by declaring members and constructors, you can customize the functionality of your classes (this is called template method).
Assuming you're doing ad hoc code or prototyping, you do instantiate abstract classes (or maybe even interfaces) from time to time. They're called anonymous inner classes (one, two) and look like this:
// you have this...
public abstract class SomeClass {
public abstract String returnAString();
}
// ...and this...
public class OtherClass {
public void operate(SomeClass c) {
System.out.println(c.returnAString());
}
}
// ...so you do this:
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
#Override
public String returnAString() {
return "I'm an anonymous inner class!";
}
});
This example is of course quite redundant but should expose the point. Some existing frameworks even rely on the heavy usage of this behaviour, namely Apache Wicket at least.