public class Test {
public static void main(String[] args) {
new Person().printPerson();
new Student().printPerson();
}
}
class Student extends Person {
private String getInfo() {
return "Student";
}
}
class Person {
private String getInfo() {
return "Person";
}
public void printPerson() {
System.out.println(getInfo());
}
}
The answer is
Person
Person
But when I change both the private access-specifiers to public, the result is
Person
Student
Why? I can't understand.
Private methods are not visible in subclasses and therefore can't be overriden. So it always invokes a method from parent class.
Related
I'm writing an abstract class and have some sub-classes extend it. I have the exact same method with the same implementation in the sub-classes, and I'm wondering if there's a way to avoid the code duplication. The problem is that although the code is completely identical in every class, it uses a static variable of the class. Is there a way to have the method written only once (in the abstract class, for example) and have the method access the static member "NAME" from the class type of the current object?
In other words, is there a way to implement the method getName() only once, and return the NAME static variable of the current type of class?
public abstract class Car {
public abstract String getName();
}
public class Bus extends car{
private static final String NAME = "Bus a Bus A";
public String getName() {
return Bus.NAME;
}
}
public class Taxi extends car{
private static final String NAME = "TAXiiii";
public String getName() {
return Taxi.NAME;
}
}
public class Motor extends car{
private static final String NAME = "motor hehe";
public String getName() {
return Motor.NAME;
}
}
Why not simply pass the name to the super constructor? Although this removes the need for Car to be abstract, because you can simply return the name from its getName method instead.
public class Car {
private final String name;
public Car(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Bus extends Car {
private static final String NAME = "Bus a Bus A";
public Bus() {
super(NAME);
}
}
public class Taxi extends Car {
private static final String NAME = "TAXiiii";
public Taxi() {
super(NAME);
}
}
public class Motor extends Car {
private static final String NAME = "motor hehe";
public Motor() {
super(NAME);
}
}
How do I pass a private String variable being assigned as "hi" in one method to a constructor so that when I call the getTemp method in another class I get the result: hi
Class LoginDialog:
private String temp;
public void action(){
String temp = "hi"
}
public LoginDialog() {
this.temp=temp;
}
public String getTemp(){
return this.temp;
}
Main:
public class main {
public static void main(String[] args) {
LoginDialog n = new LoginDialog();
String username = n.getTemp();
System.out.println(username);
}
}
So you have two classes, ClassA and ClassB. From what I understand from your question, the objective is to pass the text from the action() method in ClassA into ClassB's constructor, so that you can access it from getTemp() method.
ClassA.java
public ClassA {
public ClassA(){
}
public String action(){ // notice that the return method is `String`
return "hi";
}
}
ClassB.java
public ClassB {
private String temp;
public classB(String temp){
this.temp = temp;
}
public String getTemp(){
return this.temp;
}
}
And in your main code you can do this:
ClassA classA = new ClassA();
ClassB classB = new ClassB(classA.action());
System.out.println(classB.getTemp()); //result will be 'hi'
1.You can do it by this.
class LoginDialog {
private String temp;
public void action(){
this.temp="hi";
}
public LoginDialog(){
action();
}
public String getTemp(){
return this.temp;
}
}
public class main {
public static void main(String[] args) {
LoginDialog n = new LoginDialog();
String username = n.getTemp();
System.out.println(username);
}
}
I am trying to use a getter to retrieve some variables that the user will input into a GUI, however it gives me an "non-static method cannot be referenced from a static context" error. I have tried making my getters and setters static and that did not work. I am not sure where to go from there. Here is my code:
Main:
public class creditInfoSystem {
String name = infoGUI.getName();
public static void main(String[] args) {
new infoGUI();
}
public void getData() {
}
}
Getters+Setters From GUI Class:
public void setName(String newName){
name = newName;
}
public String getName(){
return name;
}
public void setCustNum(double newCustNum){
custNum = newCustNum;
}
public double getCustNum(){
return custNum;
}
public void setCreditLimit(double newCreditLimit){
creditLimit = newCreditLimit;
}
public double getCreditLimit(){
return creditLimit;
}
public void setPrevBalance(double newPrevBalance){
prevBalance = newPrevBalance;
}
public double getPrevBalance(){
return prevBalance;
}
public void setCurrentPurchases(double newCurrentPurchases){
currentPurchases = newCurrentPurchases;
}
public double getCurrentPurchases(){
return currentPurchases;
}
public void setPayments(double newPayments){
payments = newPayments;
}
public double getPayments(){
return payments;
}
public void setCreditsReturns(double newCreditsReturns){
creditsReturns = newCreditsReturns;
}
public double getCreditsReturns(){
return creditsReturns;
}
public void setLateFees(double newLateFees){
lateFees = newLateFees;
}
public double getLateFees(){
return lateFees;
}
I can provide more parts of the code if needed.
The problem is that the creditInfoSystem class has no idea which infoGUI class you are referring to. Try and make infoGUI a parameter of creditInfoSystem and retrieve the data from there.
public class creditInfoSystem {
private InfoGUI infoGUI;
public creditInfoSystem(InfoGUI gui){
infoGUI = gui;
name = infoGUI.getName();
}
public static void main(String[] args) {
InfoGUI infoGUI = new infoGUI();
CreditInfoSystem sys = new creditInfoSystem(infoGUI);
}
}
If you are building a swing/FX GUI:
One problem I can predict is knowing when the name in the GUI is actually set. You should maybe consider making the GUI the main program where CreditInfoSystem is an attribute of the GUI. Then when a button is clicked or some other action, the input from the GUI is taken and passed to the CreditInfoSystem.
First of all, rename your classs InfoGUI and CreditInfoSystem, starting with an upper case, it is a Java convention.
Then, when you do InfoGUI.getName() you are trying to access a class method, which would have to be static. What you want to do is create an instance of InfoGUI and access it's instance method.
Also your name variable should be static because you use it in a static method, ie public static void main
public class CreditInfoSystem {
private static String name;
public static void main(String[] args) {
// Create an instance of your InfoGUI class
InfoGUI infoGuiInstance = new InfoGUI();
// Call the getter on the instance you just created
name = infoGuiInstance.getName();
}
}
And the renamed InfoGUI class:
class InfoGUI {
String name;
public void setName(String newName) {
name = newName;
}
public String getName() {
return name;
}
}
how do I call a void method from another class to a new class with main?
I have two classes, but I don't see the error I am making.
public class Person {
private int age;
private String name;
public Person(int a, String n) {
a = age;
n = name;
}
public void printInfo() {
System.out.println(age + name);
}
//
public class Main {
public static void main(String[] args) {
Person obj1 = new Person(22, "Dan");
obj1.printInfo();
}
}
EDIT: Move the main method to a different class and done.
TestPerson.java
public class TestPerson {
public static void main(String[] args) {
Person obj1 = new Person(22, "Dan");
obj1.printInfo();
}
}
You have few mistakes in your code. It should be like as follows :
public class Person {
private int age;
private String name;
//Your constructor was wrong
public Person(int a, String n) {
age = a;
name = n;
}
public void printInfo() {
System.out.println(age + name);
}
}
I have the following example in Java:
public abstract class Vehicle {
private final String name;
private final String make;
public Vehicle(final String name, final String make) {
this.make = make;
this.name = name;
}
}
public final class Car extends Vehicle {
public Car(final String name, final String make) {
super(name, make);
}
}
public final class Truck extends Vehicle {
final Integer grossVehicleWeight;
public Truck(final String name, final String make, final Integer gvw) {
super(name, make);
this.grossVehicleWeight = gvw;
}
Say I want to do some work with a vehicle, and the work is not dependent on the subclass of vehicle. So, I have a method in another class like this:
public void doStuff(public final Vehicle vehicle) {
//do stuff here
//then insert it into my database:
insertVehicle(vehicle);
}
However, I want to do different things in my insertVehicle, so I override that method for each subclass:
public void insertVehicle(Car car) { //do stuff for a car }
public void insertVehicle(Truck truck) { //do stuff for a truck }
In my doStuff method, I could use instanceOf to determine the class of the vehicle (Car or Truck), and then cast the vehicle into that class and call the insertVehicle method like this:
public void doStuff(public final Vehicle vehicle) {
//do stuff here
//then insert it into my database:
if (vehicle instanceof Car) {
insertVehicle((Car) vehicle);
} else {
insertVehicle((truck) vehicle);
}
}
However, I have read that using instanceof is not the best way to do this. 1
How could I best rework this so that I do not have to use instanceof?
You can use the Visitor Pattern:
public interface VehicleVisitor {
public void visit(Car car);
public void visit(Truck truck);
}
public class Car extends Vehicle {
#Override
public void insert(VehicleVisitor vehicleVisitor) {
vehicleVisitor.visit(this);
}
}
public class Truck extends Vehicle {
#Override
public void insert(VehicleVisitor vehicleVisitor) {
vehicleVisitor.visit(this);
}
}
public abstract class Vehicle {
public abstract void insert(VehicleVisitor vehicleVisitor);
}
public class VehicleVisitorImpl implements VehicleVisitor {
#Override
public void visit(Car car) {
System.out.println("insert car");
}
#Override
public void visit(Truck truck) {
System.out.println("insert truck");
}
}
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Car();
// finally the agnostic call
vehicle.insert(new VehicleVisitorImpl());
}
}
You can make the abstract function inside the vehicle for
public abstract void doStuff()
call this function from the instance of the object that you want to modify
ford.doStuff(); //ford is car instance
and then you can make modification using this.
doStuff()
{
this.cost += 10;
}
Otherwise, you can add a variable for vehicle which indicated what is the vehicle type and return it. Like:
public void doStuff(public final Vehicle vehicle) {
//do stuff here
//then insert it into my database:
if (vehicle.getType()== 'Car') {
insertVehicle((Car) vehicle);
} else {
insertVehicle((truck) vehicle);
}
}
This variable 'vehicleType' will be in the vehicle class and will be initialized inside the constructor:
public final class Car extends Vehicle {
public Car(final String name, final String make, final String vehicleType) {
super(name, make, type);
}
}
It depends on what kind of problem you trying to solve. If it is persistency make sure you are not reinventing JPA. If it is type-specific processing then you can solve it as #denis suggested. Or if you want to keep entities in POJO-style you can use strategy pattern like:
Map<Class<?>, Consumer<Vehicle>> consumers;
{
consumers.put(Car.class, v -> insertVehicle((Car)v));
consumers.put(Truck.class, v -> insertVehicle((Truck)v));
}
public void doStuff(public final Vehicle vehicle) {
//do stuff here
consumers
.get(vehicle.getClass())
.accept(vehicle);
}
One way is to have the insertVehicle() method abstract in Vehicle. And then implement them in the subclasses Car and Truck.
However, this moves the logic into the POJOs. Maybe it is better to separate db-logic from the POJOs, i.e. just use instanceof in this case.
public abstract class Vehicle {
private final String name;
private final String make;
public Vehicle(final String name, final String make) {
this.make = make;
this.name = name;
}
public abstract void insertVehicle();
}
public final class Car extends Vehicle {
public Car(final String name, final String make) {
super(name, make);
}
public void insertVehicle() {
}
}
public final class Truck extends Vehicle {
final Integer grossVehicleWeight;
public Truck(final String name, final String make, final Integer gvw) {
super(name, make);
this.grossVehicleWeight = gvw;
}
public void insertVehicle() {
}
}
public void doStuff(Vehicle vehicle) {
//do stuff here
//then insert it into my database:
vehicle.insertVehicle();
}
If you don't like putting doStuff() into Car and Truck, you could have a doStuff() method for each of them, and put the common Vehicle logic into another method.
private void doCommonStuff(final Vehicle vehicle) {
//do stuff here
}
public void doStuff(final Car car) {
doCommonStuff(car);
//then insert it into my database:
insertVehicle(car);
}
public void doStuff(final Truck truck) {
doCommonStuff(truck);
//then insert it into my database:
insertVehicle(truck);
}
We can do better, though, with generics.
public abstract class StuffDoer<T extends Vehicle> {
public void doStuff(final T vehicle) {
// do stuff here
// then insert it into my database:
insertVehicle(vehicle);
}
public abstract void insertVehicle(T vehicle);
}
public class CarStuffDoer extends StuffDoer<Car> {
public void insertVehicle(Car car) {
// whatever
}
}
public class TruckStuffDoer extends StuffDoer<Truck> {
public void insertVehicle(Truck truck) {
// whatever else
}
}