so i had this exam in university which was to create book class which would have author, title, content and translator.
main requirement was to create only 1 class and create inner classes within it (author and translator)
and one Main class to test it.
Problem was that when i created author and translator objects and tried to change their names, both of them would change names.
Here's my code:
Book Class:
public class Book {
private Author author;
private Translator translator;
private String title;
private String text;
public interface IPerson {
public void setFirstName(String name);
public String getFirstName();
public void setLastName(String name);
public String getLastName();
}
//Author
public class Author implements IPerson{
private String firstName;
private String lastName;
public Author(String f, String l){
firstName = f;
lastName = l;
author = this;
}
public void setFirstName(String name){
this.firstName = name;
}
public String getFirstName(){
return this.firstName;
}
public void setLastName(String name){
this.lastName = name;
}
public String getLastName(){
return this.lastName;
}
}
public Author getAuthor(){
return this.author;
}
//Translator
public class Translator extends Author{
public Translator(String f, String l) {
super(f, l);
translator = this;
}
}
public Translator getTranslator(){
return this.translator;
}
public String getTranslatorFullName(){
return this.getTranslator().getFirstName() + " " + this.getTranslator().getLastName();
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDisplayTitle(){
return getTitle() + " Author: " + this.getAuthor().getFirstName() + " " + this.getAuthor().getLastName();
}
}
Main Class:
public class Main {
public static void main(String[] args){
Book mybook = new Book();
mybook.setTitle("Fight Club");
mybook.setText("First rule of Fight Club, you do not talk about Fight Club");
Book.Author author = mybook.new Author("John","Doe");
Book.Translator translator = mybook.new Translator("Alan","Rickman");
System.out.println(mybook.getDisplayTitle());
System.out.println(mybook.getAuthor().getLastName());
System.out.println(mybook.getAuthor().getFirstName());
System.out.println(mybook.getTranslatorFullName());
System.out.println(mybook.getTranslator().getFirstName());
}
}
It Had to pass these tests, what was my problem?
Don't tell me to make Translator implement IPerson, it was my teachers request to extend
You can fix it like this:
public Author(String f, String l, boolean authorCheck){
firstName = f;
lastName = l;
if(authorCheck)
{
author = this;
}
}
public Author(String f, String l){
firstName = f;
lastName = l;
author = this;
}
public Translator(String f, String l) {
super(f, l, false);
translator = this;
}
It would make more sense if Translator implements IPerson instead of extending Author.
You're making a super(f,l) call in the constructor of Translator. Translator is changing the Author fields as the superclass of Translator is Author.
Related
this is main method
public static void main(String[] args) {
Author[] authors=new Author[2];
for(int i=0;i<=authors.length;i++);
authors[0]=new Author("suru","suru#qwe.com","m");
authors[1]=new Author("aksh","aksh#qwe.com","m");
for(int i=0;i<=authors.length;i++);
System.out.println(authors);
Book book=new Book("java",authors,200,2);
System.out.println(book);
now i created 2nd class authoer with getter and setter
private String name;
private String email;
private String gender;
public Author (String name,String email, String gender)
{
this.name=name;
this.email=email;
this.gender=gender;
}
noow i created new class Book
public class Book {
private String name;
private Author[] author;
private double price;
private int qty=0;
public Book(String name,Author[] author,double price, int qty) {
this.name=name;
this.author=author;
this.price=price;
this.qty=qty;
}
when i run this program the output give the memory adress ho can i print theese detail
You need to override toString() method in the class Author.
For example:
#Override
public String toString() {
return "Author [name=" + name + ", email=" + email + ", gender=" + gender + "]";
}
When you pass as argument of the method System.out.println() name of variable, method toString() of the class of that variable is being called. If you don't override that method in class Author or Book, toString() method inherited by these classes from Object class is being called (all classes in Java inherit from Object class). By default, this method prints address in memory for classes with toString() not defined in their bodies. There is a simple example, how you can override it in Author method:
class Author {
#Override
public String toString() {
return "Author name: " + this.name + "\nAuthor email: " + this.email + "\nAuthor gender : " + this.gender;
}
To print contents of an array (in your example to print each Author contained in Author[] authors) you might want to use one of these way to achieve that (as Author[] or Book[] is actually a type of array and not a type of Book or Author and has its own toString() method printing address in memory) :
Create a loop iterating over each element of authors array:
for (Author author : authors) {
System.out.println(author + "------"); // toString() method of each Author is called and added simple separator
}
Call Arrays.toString(authors) method. Class Arrays is provided to let you manipulate arrays in many different ways. You can read about this class in Java API documentation. This is a part of what documentation says about Arrays.toString() method:
Returns a string representation of the contents of the specified array. If the array contains other arrays as elements, they are converted to strings by the Object.toString() method inherited from Object, which describes their identities rather than their contents.
package oops;
public class Main {
public static void main(String[] args) {
Author[] authors=new Author[2];
for(int i=0;i<=authors.length;i++);
authors[0]=new Author("suru","suru#qwe.com","m");
authors[1]=new Author("aksh","aksh#qwe.com","m");
for(int i=0;i<=authors.length;i++);
System.out.println(authors);
Book book=new Book("java",authors,200,2);
System.out.println(book);
}
}
package oops;
public class Author {
private String name;
private String email;
private String gender;
public Author (String name,String email, String gender)
{
this.name=name;
this.email=email;
this.gender=gender;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String toString() {
return name+ " " +email+ " " +gender+ " ";
}
package oops;
public class Book {
private String name;
private Author[] author;
private double price;
private int qty=0;
public Book(String name,Author[] author,double price, int qty) {
this.name=name;
this.author=author;
this.price=price;
this.qty=qty;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public String getName() {
return name;
}
/*public Author[] getAuthor() {
return author;
} */
public Author[] getAuther() {
for (int i=0;i<=author.length;i++);
return author;
}
public String toString() {
return name+" "+author+" "+price+" "+qty+" ";
}
public Author[] getAutherNames() {
for (int i=0;i<=author.length;i++);
return author;
}
}
this is my full program
You an override toString() or you can print the attributes of the object directly as follows:
Book b = new Book(/*args*/);
System.out.println("Name: " + b.name);
// continue printing all the attributes in the same way
You can try this instead of overriding toString() method in the object class.
Hope this helps...
I am working on a project that links books to their authors.The author info is part of the book class and it is an Author object in the book class and its data will become part of the book class. I have the author class:
public class Author {
private String Name;
private String email;
private char gender;
public Author( ) {
Name="Emily";
email="email#email.com";
gender='f';
}
public String getName (){
return Name;
}
public void setName (String Name){
this.Name=Name;
}
public String getEmail (){
return email;
}
public void setEmail(String email){
this.email=email;
}
public char getGender (){
return gender;
}
public void setGender(char gender){
this.gender=gender;
}
public String toString () {
String x = "Name: " + Name + "email " + "gender: " + gender;
return x;
}
}
and the book class:
public class Book {
private String name;
private Author author;
private double price;
private int quantity;
public Book (){
name="Book Name";
author=Author.toString();
price=11.79;
quantity=2;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public Author getAuthor(){
return author;
}
public void setAuthor () {
this.author=author;
}
public double getPrice () {
return price;
}
public void setPrice (double price) {
this.price=price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity (int quantity) {
this.quantity=quantity;
}
public String toString (){
String x = "Book is " + name + "Author and author info "+ author + "Price " + price + "Quantity " + quantity;
return x;
}
}
I need to store the contents of the toString() method in the Author variable in the book class as the author info. How do I do this?
You don't need to store the value of the toString() method of the Author class, this would couple your classes unnecessarily and break one of the core principals of good OO design.
The toString method of the Author class should be responsible for presenting a sensible String representation of its state (which it seems to). Your book class should do the same, delegating to classes it interacts with to do the same:
public String toString() {
return "Book is " + name + "Author and author info "+ author.toString() + "Price " + price + "Quantity " + quantity;
}
As noted in the comments, you're already doing this in the code snippet posted in the question, your question implies that this this may have not been 'by design'. I would recommend researching Object Encapsulation and delegation.
I have the following structure:
Member {
String firstName;
String secondName;
Member[] children;
Member father;
}
I have to implement this tree in java;
I have a first name and a second name of a member. I need to find the way from root to that node.
Can someone help me, please?
This is what i have:
public class Member {
public List<Member> children = new ArrayList<>();
public Member father = null;
public String secondName = null;
public String firstName = null;
public Member(String secondName, String firstName) {
this.secondName = secondName;
this.firstName = firstName;
}
public Member(String secondName, String firstName, Member father) {
this.secondName = secondName;
this.firstName = firstName;
this.father = father;
}
public List<Member> getChildren() {
return children;
}
public void setFather(Member father) {
this.father = father;
father.addChild(this);
}
public void addChild(String secondName, String firstName) {
Member child = new Member(secondName, firstName);
child.setFather(this);
this.children.add(child);
}
public void addChild(Member child) {
child.setFather(this);
this.children.add(child);
}
public String getSecondName() {
return this.secondName;
}
public String getFirstName() {
return this.firstName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public void setPrenume(String firstName) {
this.firstName = firstName;
}
public boolean isRoot() {
return (this.father == null);
}
public void deleteFather() {
this.father = null;
}
}
Your structure is similar to ona which i have in my application. I solve this problem by creating generic walker, which walks down the three from the root, and using visitor pattern to provide me result of walk.
If you convert it into your problem it will looks like that:
public class SimpleWalker<T>{
private Visitor<T> visitor;
public SimpleWalker(Visitor<T> visitor) {
this.visitor= visitor;
}
public void walk(Member node) {
if (visitor.visit(node)) {
for (Member child : node.children) {
walk(child);
}
}
visitor.leave(node);
}
public T getResult() {
return visitor.getResult();
}
}
then visitor interface
public interface Visitor<T> {
boolean visit(Member node);
void leave(Member node);
T getResult();
}
and implementation will looks like that
public class Pathfinder implements Visitor<List<Member>> {
final private String firstname, secondname;//passed by constructor
boolean found = false;
List<Member> path = new ArrayList<>();
public boolean visit(Member node) {
if (node.firstname.equals(firstname)
&& node.secondname.equals(secondname)) {
found = true;
return false;
}
return true;
}
public void leave(Member node) {
if (found){
path.add(0, node);
}
}
public List<Member> getResult() {
return path;
}
}
advantage of this solution is, whatever you want to do something in tree, such us find element, count number of descendants of somebody, you can use walker, all what you need to do is create new visitor.
This Github project might help if you want to create a Family Tree using Java swing:
https://github.com/r-deleon/familyTree
It uses yFiles for Java library..
I have a actionform class:
public class NameForm extends ActionForm {
private String firstName;
private String lastName;
public void setLastName(String lName) {
lastName = lName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String fName) {
firstName = fName;
}
public String getFirsttName() {
return firstName;
}
}
and I have another class that contains other getters/setters that I would like to use in my action form it is:
public class sports {
private String sport;
private String team;
private String position;
public void setSport(String sp) {
sport = sp;
}
public String getSport() {
return sport;
}
public void setTeam(String tm) {
team = tm;
}
public String getTeam() {
return team;
}
public void setPosition(String po) {
position = po;
}
public String getPosition() {
return position;
}
}
How can I get the values contained in the getters for the sports class into the actionform without creating another actionform? I am trying to use beans to populate my jsp from my action form.
To do this you can create another attribute in your NameForm that is of type Sports.
private Sports sports = new Sports();
public void setSports(Sports s){ this.sports = s; }
public Sports getSports(){ return this.sports; }
Then in your JSP you can access it using assuming you're using something like OGNL.
%{#attr.sports.team}
%{#attr.sports.position}
%{#attr.sports.sport}
Recently I am doing a coding exercises I need to make my project , and so far I am practicing it with the code below what I want to ask is that, is this a has a relationship? am I doing the right practice? look at my code, sorry for my bad english
public class Personal {
private String firstName;
private String middleInitial;
private String lastName;
private int age;
public Personal(String firstName,String middleInitial , String lastName , int age){
setFirstName(firstName);
setMiddleInitial(middleInitial);
setLastName(lastName);
setAge(age);
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public String getFirstName(){
return firstName;
}
public void setMiddleInitial(String middleInitial){
this.middleInitial = middleInitial;
}
public String getMiddleInitial(){
return middleInitial;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
public String getLastName(){
return lastName;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public String toString(){
return String.format("First Name: "+getFirstName()+"\nMiddle Initial: "+getMiddleInitial()+
"\nLast Name: "+getLastName()+"\nAge: "+getAge());
}
}
Contact Class
public class Contact {
private String address;
private String email;
private String contactNumber;
public Contact(String address,String contactNumber, String email){
setAddress(address);
setContactNumber(contactNumber);
setEmail(email);
}
public void setAddress(String address){
this.address = address;
}
public String getAddress(){
return address;
}
public void setEmail(String email){
this.email = email;
}
public String getEmail(){
return email;
}
public void setContactNumber(String contactNumber){
this.contactNumber = contactNumber;
}
public String getContactNumber(){
return contactNumber;
}
public String toString(){
return String.format("Address: "+getAddress()+"\nContact Number: "+getContactNumber()+
"\nEmail Address: "+getEmail());
}
}
Employee Class
public class Employee {
private Personal personal;
private Contact contact;
public Employee(Personal personal, Contact contact){
this.personal = personal;
this.contact = contact;
}
public void setFirstName(String firstName){
this.personal.setFirstName(firstName);
}
public String toString(){
return String.format(personal.toString()+contact.toString());
}
}
And the Test class
public class TestClass {
public static void main(String[] args){
Personal personalHerp = new Personal("John","M","Doe",18);
Contact contactHerp = new Contact("88 Herp Derp St U mad New york","724-15-70","fido.com");
Employee employeeHerp = new Employee(personalHerp,contactHerp);
System.out.println(employeeHerp);
}
}
Well, since Employee doesn't extend Personal it has a Personal and a Contact.
I guess you'd rather like Employee to be a Personal and thus it should look like this:
public class Employee extends Personal {
private Contact contact;
...
}
So to summarize:
is-a means a class/object extends another class or implements an interface, i.e. A is-a B if A extends B or A implements B
has-a means that a class/object has a variable of that type, like Contact contact in your Employee class, which means Employee has-a contact.
Yes, this is a "has-a" relationship (exactly as we discussed in your other question).