Why I have to use sometimes protected and sometimes not? - java

I have 2 differents programs that use class and class child.
In both of the program I use private field. But in the first program that has for parent class "Car" I have no problem with private field, the children can has access to. But in the second program that has "Hamburger" for parent class, the children can not has acces to the fields :
First program (the program is working)
public class Car {
private boolean engine;
private int cylinders;
private String name;
private int wheels;
public Car(int cylinders, String name) {
this.cylinders = cylinders;
this.name = name;
this.wheels = 4;
this.engine = false;
}
}
public class Mitsubishi extends Car {
public Mitsubishi() {
super(5, "Mitsubishi");
}
}
Second program (not working)
public class Hamburger {
private String name;
private String meat;
private double price;
private String breadRollType;
private String addition1;
private String addition2;
private String addition3;
private String addition4;
public Hamburger(String name, String meat, double price, String breadRollType) {
if (price < 0) {
price = 0;
}
this.name = name;
this.meat = meat;
this.price = price;
this.breadRollType = breadRollType;
this.addition1 = "none";
this.addition2 = "none";
this.addition3 = "none";
this.addition4 = "none";
}
}
public class DeluxeBurger extends Hamburger{
public DeluxeBurger() {
super("Deluxe Burger", "Steak", 19.10, "Chic bread");
}
}
I have seen that I can use protected and it's fix the probelem, but I don't know why I have to use protected on the second program (with the Hamburger) but not on the first (with the Car).

I copy your code and past to my project and see your problem.
i dont know Why, maybe its a bug. but if you create new package and drop this two class into new package Your problem will be solved and you will not see this problem again. It was interesting for me.
thanx

Related

Argument errorr in Java Nested Builder Pattern

I am learning the Java Builder Pattern from Section 6.1 (Builder Pattern Example) at: https://www.baeldung.com/creational-design-patterns#factory-method
But after I run my own code, it shows the error, wonder if could anyone help to point out where is wrong? Thanks a lot in advance.
class Test {
public static void main(String[] args) {
BankAccount newAccount = new BankAccount.BankAccountBuilder("Jon", "22738022275").withEmail("jon#example.com").wantNewsletter(true).build();
System.out.print(newAccount);
}
}
public class BankAccount {
private String name;
private String accountNumber;
private String email;
private boolean newsletter;
// constructors/getters
public static class BankAccountBuilder {
private String name;
private String accountNumber;
private String email;
private boolean newsletter;
public BankAccountBuilder(String name, String accountNumber) {
this.name = name;
this.accountNumber = accountNumber;
}
public BankAccountBuilder withEmail(String email) {
this.email = email;
return this;
}
public BankAccountBuilder wantNewsletter(boolean newsletter) {
this.newsletter = newsletter;
return this;
}
public BankAccount build() {
return new BankAccount(this);
}
}
}
You are missing the private constructor, something like:
//The constructor that takes a builder from which it will create the object
//the access to this is only provided to builder
private BankAccount(BankAccountBuilder builder) {
this.name = builder.name;
this.accountNumber = builder.accountNumber;
this.email = builder.email;
this.newsletter = builder.newsletter;
}
I assume the article leaves it to the reader in the section that says // constructors/getters on the code.
In addition, not completely related but the System.out.print you have will not print the object but its reference, you don't have a toString() method.
This is probably a duplicate but you just didn't declare a constructor. This code needs a constructor:
public class BankAccount {
private String name;
private String accountNumber;
private String email;
private boolean newsletter;
// constructors/getters
// ** you didn't put anything here **
So just add a constructor
// constructors/getters
private BankAccount( BankAccountBuilder b ) {
// initialize your class here
}

I am getting a getInstance() error occurs when trying to create a Singleton

I know there is lots online and I have been looking for the last two hours trying to fix my code.
I am making a immutable class called Car I have seen lots of videos and read articles online.
Even my notes from college talk about creating a Singleton class when make a class Immutable (my notes are rubbish as usual).
Anyway the code below has everything I have seen in videos and read in articles the only difference is in everything I watched and read is their Objects did not have other variables.
public final class Car{
private static Car carSingleton = null;
private final String owner;
private final String reg;
private final String make;
private final int kilometres;
private final double price;
private Car() {}
public static Car getInstance()() {
if(carSingleton == null) {
carSingleton = new Car();
}
return carSingleton;
}
public String getOwner(){return owner;}
public String getReg(){return reg;}
public String getMake(){return make;}
public int getKilometres(){return kilometres;}
public double getPrice(){return price;}
}
I am getting a an error in the getInstance() constructor Car() is undefined.
EDIT:
Here is the actual question I was given
Question 1
Given below is a mutable Car class. Re-write it so that it becomes immutable and write a simple test program.
class Car{
private String owner;
private String reg;
private String make;
private int kilometres;
private double price;
public Car(String owner, String reg, String make, int kilometres, double price){
this.owner = owner; this.reg = reg;this.make = make;
this.kilometres = kilometres; this.price = price;
}
public String owner(){return owner;}
public String reg(){return reg;}
public String make(){return make;}
public intkilometres(){return kilometres;}
public double price(){return price;}
public void setPrice(double p){price = p;}
public void setOwner(String ow){owner = ow;}
public void setKil(int k){kilometres = k;}
public void setMake(String m){make = m;}
}
To make this class immutable remove the setters. It should not be Singleton.
class Car{
private String owner;
private String reg;
private String make;
private int kilometres;
private double price;
public Car(String owner, String reg, String make, int kilometres, double price){
this.owner = owner; this.reg = reg;this.make = make;
this.kilometres = kilometres; this.price = price;
}
public String getOwner(){return owner;}
public String getReg(){return reg;}
public String getMake(){return make;}
public getKilometres(){return kilometres;}
public double getPrice(){return price;}
}
In your getInstance() you are calling a constructor which is not defined:
carSingleton = new Car();
Define a default constructor to fix the error:
private Car() {
// initialize final variables
}
or use some other constructor in getInstance()
Answering the EDIT part:
If a type (class) is immutable it only means you can't change its instances once you create them. Only thing you need to do in your assignment is remove all of the set methods and make all class attributes final.
Like you said, your notes are not helping you at all. Singleton should not be used for this purpose.

Calling methods in the main program

I am trying to access some information that my program isnt letting me.
in my method "addTrack" it doesnt recognise the myTracklist object. how do i call myTracklist.count by using a method in the main class?
public class CD {
String art;
String tit;
public CD(String artist, String title){
art = artist;
tit = title;
tracklist myTracklist = new tracklist(100);
}
public static void main(String[] args) {
String mainArtist;
String mainTitle;
CD myCD = new CD("Awesomeguy", "AwesomeCDName");
mainArtist = myCD.getArtist();
System.out.println(mainArtist);
mainTitle = myCD.getTitle();
System.out.println(mainTitle);
myCD.display();
}
public String getArtist(){
String person;
person = art;
return person;
}
public String getTitle(){
String name;
name = tit;
return name;
}
public boolean addTrack(String trackinfo){
boolean result = false;
if (myTracklist.count < 100){
myTracklist.add(trackinfo);
result = true;
}
return result;
}
public int numTracks(){
int amount;
amount = myTracklist.count();
return amount;
}
public void display(){
System.out.println("Artist = "+ art);
System.out.println("Title = "+ tit);
tracklist.display();
}
}
here is my tracklist class
public class tracklist {
int length;
int numUsed;
String[] storage;
public tracklist(int size){
length = size;
numUsed = 0;
storage = new String[length];
}
public int count(){
return numUsed;
}
}
You've got scope problems in that you're declaring tracklist inside the CD constructor so that it only exists inside of the constructor and nowhere else. You must make it a field that is declared in the class for it to be usable at all the methods of the class.
So instead of
public class CD {
String art;
String tit;
public CD(String artist, String title){
art = artist;
tit = title;
tracklist myTracklist = new tracklist(100);
}
do
public class CD {
private String art;
private String tit;
private tracklist myTracklist; // declared
public CD(String artist, String title){
art = artist;
tit = title;
myTracklist = new tracklist(100); // initialized
}
// getter and setter methods of course.
It's a subtle but important distinction.
As an aside: you'll want to learn Java naming conventions so that others can more readily understand your code and your questions. Class names begin with an upper case letter.
As a second aside: don't have outside classes directly manipulate class fields. Use private fields and public getters and setters to allow the class to have more control over just what can be seen and what can be done.
it should be myTracklist.count() here:
if (myTracklist.count < 100){
Also:
String tit; // oh I love this object name!
tracklist myTracklist;
public CD(String artist, String title){
art = artist;
tit = title;
myTracklist = new tracklist(100);
}
Since you have declared it in your customer the "myTracklist" variable will only be visible in your constructor. Hence "addTrack" doesnt recognise the myTracklist object.
Declare it globally,
public class CD {
String art;
String tit;
tracklist myTracklist;
And initialize in the constructor as below.
myTracklist = new tracklist(100);
Keep the declaration of myTrackList outside the constructor. Like this:-
String tit;
tracklist myTracklist;
public CD(String artist, String title){
art = artist;
tit = title;
myTracklist = new tracklist(100);
}

How to use a variable of one class, in another in Java?

I'm just working through a few things as practice for an exam I have coming up, but one thing I cannot get my head round, is using a variable that belongs to one class, in a different class.
I have a Course class and a Student class. Class course stores all the different courses and what I simply want to be able to do is use the name of the course, in class Student.
Here is my Course class:
public class Course extends Student
{
// instance variables - replace the example below with your own
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
And here is Student:
public class Student
{
// instance variables - replace the example below with your own
private int studentNumber;
private String studentName;
private int studentPhone;
private String studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = courseTitle;
}
}
Am I correct in using 'extends' within Course? Or is this unnecessary?
In my constructor for Student, I am trying to assign 'courseTitle' from class Course, to the variable 'studentCourse'. But I simply cannot figure how to do this!
Thank you in advance for your help, I look forward to hearing from you!
Thanks!
Am I correct in using 'extends' within Course? Or is this unnecessary?
Unfortunately not, if you want to know whether your inheritance is correct or not, replace extends with is-a. A course is a student? The answer is no. Which means your Course should not extend Student
A student can attend a Course, hence the Student class can have a member variable of type Course. You can define a list of courses if your model specifies that (a student can attend several courses).
Here is a sample code:
public class Student{
//....
private Course course;
//...
public void attendCourse(Course course){
this.course = course;
}
public Course getCourse(){
return course;
}
}
Now, you can have the following:
Student bob = new Student(...);
Course course = new Course(...);
bob.attendCourse(course);
I assume a Course is not a Student, so inheritance between those classes is probably a bad idea.
You have to declare them public.
A better way is the keep them private, and code a public getter for that variable. for example:
public Award getCourseAward(){
return this.courseAward;
}
Course should not extend Student. If you want to access the courseTitle field of Course, you need to pass a reference to a Course object to the Student and then do course.CourseTitle.
You cannot access private attributes of a class from another, this is one of the main principles of OOP: encapsulation. You have to provide access method to those attribute, you want to publish outside the class. The common approach is setter/getters - getters only, if you want to have your class immutable. Look here: http://en.wikipedia.org/wiki/Mutator_method#Java_example
It does not make sense to arbitrarily extend classes. Student is not a Course or vice versa, so you cannot extend them like that.
What you need to do is:
create a Course first:
Course aCourse = new Course(..);
create a Student:
Student aStudent = new Student(..);
assign the Course to the Student:
aStudent.setCourse(aCourse.title);
Extending Student with Couse because they are not of the same kind. Extending one class with another happens when specializing a more general (in a sense) one.
The solution would be to pass courseTitle as an argument of the Student constructor
There should be 3 separate objects here, a Course, a Student, and an Enrollment. An enrollment connects a Student to a Course, a Course has many Students, and a Student can enroll in many courses. None of them should extend each other.
First,
You are extending Student class in Course class, which means, student class gets all the coruse class properties. So, the student class does not have the courseTitle property.
Second, yes, it is unnesessary - you need to do the following:
public class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
public class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
// This is where you keep the course object associated to student
public Course studentCourse;
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
}
Example usage would be something like this:
Course course = new Course("ASD", "TITLE", null, "ME", 50, true);
Student student = new Student(1, "JOHN", "5551234", course);
And then, get the course information you need from student via, i.e.:
student.studentCourse.courseTitle;
Since now student.studentCourse will be a course object with all of its properties.
Cheers,
Maybe you do not need to add the course name to student. What I would do is add Students to some datastructure in Course. This is cleaner and reduces the coupling between Course and Student. This would also allow you to have Students being in more than one course. For example:
public class Course extends Student{
private Award courseAward;
private String courseCode;
public String courseTitle;
private Student courseLeader;//change to a student Object
private int courseDuration;
private boolean courseSandwich;
private Set<Student> students;//have course hold a collection of students
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, Student leader, int duration, boolean sandwich){
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
this.students=new HashSet<Student>();
}
public boolean addStudent(Student student){
return students.add(student);
}
public Set<Student> getStudents(){
return students;
}
}
As mentioned, stay away from the "extends" for this. In general, you shouldn't use it unless the "is-a" relationship makes sense.
You should probably provide getters for the methods on the Course class:
public class Course {
...
public String getTitle() {
return title;
}
}
And then if the Student class needs that, it would somehow get a hold of the course (which is up to you in your design), and call the getter:
public class Student {
private Set<Course> courses = new HashSet<Course>();
public void attendCourse(Course course) {
courses.add(course);
}
public void printCourses(PrintStream stream) {
for (Course course : courses) {
stream.println(course.getTitle());
}
}
}
Here below find out the solution of your problem and if you want to check below code on your machine then create a file named Test.java and paste the below codes:
package com;
class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseAward = award;
courseCode = code;
courseTitle = title;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
public Award getCourseAward() {
return courseAward;
}
public void setCourseAward(Award courseAward) {
this.courseAward = courseAward;
}
public String getCourseCode() {
return courseCode;
}
public void setCourseCode(String courseCode) {
this.courseCode = courseCode;
}
public String getCourseTitle() {
return courseTitle;
}
public void setCourseTitle(String courseTitle) {
this.courseTitle = courseTitle;
}
public String getCourseLeader() {
return courseLeader;
}
public void setCourseLeader(String courseLeader) {
this.courseLeader = courseLeader;
}
public int getCourseDuration() {
return courseDuration;
}
public void setCourseDuration(int courseDuration) {
this.courseDuration = courseDuration;
}
public boolean isCourseSandwich() {
return courseSandwich;
}
public void setCourseSandwich(boolean courseSandwich) {
this.courseSandwich = courseSandwich;
}
}
class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
private Course studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentPhone() {
return studentPhone;
}
public void setStudentPhone(int studentPhone) {
this.studentPhone = studentPhone;
}
public Course getStudentCourse() {
return studentCourse;
}
public void setStudentCourse(Course studentCourse) {
this.studentCourse = studentCourse;
}
}
class Award{
private long awardId;
private String awardName;
Award(long awardId, String awardName){
this.awardId = awardId;
this.awardName = awardName;
}
public long getAwardId() {
return awardId;
}
public void setAwardId(long awardId) {
this.awardId = awardId;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
}
public class Test{
public static void main(String ar[]){
// use your all classes here
}
}

Create a default constructor in Java

I need to create a method with a default constructor, which sets name to an empty string and sets both credits and contactHours to zero. How to do it? Thanks, Pieter.
Methods don't have constructors... classes do. For example:
public class Dummy
{
private int credits;
private int contactHours;
private String name;
public Dummy()
{
name = "";
credits = 0;
contactHours = 0;
}
// More stuff here, e.g. property accessors
}
You don't really have to set credits or contactHours, as the int type defaults to 0 for fields anyway.
You're likely to want at least one constructor which takes initial values - in which case your parameterless one can delegate to that:
public class Dummy
{
private String name;
private int credits;
private int contactHours;
public Dummy()
{
this("", 0, 0);
}
public Dummy(String name, int credits, int contactHours)
{
this.name = name;
this.credits = credits;
this.contactHours = contactHours;
}
// More stuff here, e.g. property accessors
}
public class Test {
private String name;
private int credits;
private int contactHours;
public Test {
this( "", 0, 0);
}
public Test (String name, int credits, int contactHours) {
this.name = name;
this.credits = credits;
this.contactHours = contactHours;
}
// more code here
}
public class Bibabu{
private String name;
private int credits;
private int contactHours;
public Bibabu(){
name = ""; // you could also write this.name and so on...
credits = 0;
contactHours= 0;
}
// more code here
}
You don't need a constructor:
public class Dummy
{
private int credits = 0;
private int contactHours=0;
private String name="";
/*
public Dummy()
{
name = "";
credits = 0;
contactHours = 0;
}
*/
// More stuff here, e.g. property accessors
}
//constructor
public Account(int id, double balance, Person owner){
this.id = id;
this.balance = balance;
this.owner = owner;

Categories

Resources