How is the following program correct?
abstract class Calculate
{
abstract int multiply(int a, int b);
}
public class Main
{
public static void main(String[] args)
{
int result = new Calculate()
{
#Override
int multiply(int a, int b)
{
return a*b;
}
}.multiply(12,32);
System.out.println("result = "+result);
}
}
We are changing the scope of the overridden method here.It is not public anymore and it should of default scope.Is the scope change of overridden method allowed?
You are creating an anonymous subclass in your current code, but you are very close to having a functional interface. Let's change it to that, like
#FunctionalInterface
interface Calculate {
int multiply(int a, int b);
}
Now you have a single abstract method and can use fancy lambdas. Like,
public static void main(String[] args) {
Calculate calc = (a, b) -> a * b;
int result = calc.multiply(12, 32);
System.out.println("result = " + result);
}
Note this is exactly like your original example, just syntactic sugar added with Java 8.
From your code, it multiply is not public to begin with. If you change your mulyiply method your Calculate class to
public abstract int multiply(int a, int b);
then it will not work.
According to your code, the calculate method is not in public scope, so you are not changing the scope.
abstract class Calculate {
public abstract int multiply(int a, int b);
}
public class MyClass {
public static void main(String[] args) {
int result = new Calculate() {
#Override
public int multiply(int a, int b) {
return a * b;
}
}.multiply(11,11);
System.out.println("result = " + result);
}
}
The access level cannot be more restrictive than the overridden method's access level. For example: If the super class method is declared public then the overriding method in the subclass cannot be either private or protected.
Now there is a separate scope as default scope introduced in java , so you can call it as package private scope.
For rules of overriding in java you can follow the Link
Related
I have three static methods each in their own public classes. Simple arithmetic methods to help me learn.
The methods use three variables that when defined as static int variables in the main method. The program works.
Now according to my understanding of what I have read, I should be able to move the variable definition to another class and define them as public. The main method in its own public class should then be able to find these definitions and run. But this does not happen. Instead my eclipse workspace reports that the definitions cannot be resolved to a variable.
Here is the very simple code (which gives me the compilation error):
package christmas;
public class addintegers {
public int number1 = 5;
public int number2 = 10;
public int answer;
public static int add2numbers(int a, int b) {
return (a + b);
}
}
class 2
package christmas;
public class subtractintegers {
public static int sub2numbers(int a, int b) {
return (a - b);
}
}
Then I have my main method. This is where I am getting the compilation error.
package christmas;
public class glue {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(addintegers.add2numbers(number1, number2));
System.out.println(subtractintegers.sub2numbers(number1, number2));
answer = (addintegers.add2numbers(number1, number2)) + (subtractintegers.sub2numbers(number1, number2));
System.out.println("answer =" + answer);
}
}
the errors I get are:
>create local variable number1
>create local variable number2
>create local variable answer
First off:
Class names should be nouns, and use UpperCamelCase
Method names should be verbs, and use lowerCamelCase
E.g., something along the lines of:
public class Addition {
public static int add(int a, int b) {
return a + b;
}
}
public class Subtraction {
public static int subtract(int a, int b) {
return a - b;
}
}
If you want to have number1, number2, and answer fields in the class that I renamed Addition, normally what you would do is make them private instance variables and expose them through getters:
public class Addition {
private int number1 = 5;
public int getNumber1() {
return number1;
}
}
You can then access them by creating an instance of the class, e.g.: new Addition().getNumber1();. Since the Addition and Subtraction classes seem to be utility classes however, perhaps it makes more sense to declare these fields private static so you won't have to instantiate the classes:
public class Addition {
private static int number1 = 5;
public static int getNumber1() {
return number1;
}
}
You can then access them by referencing the class as opposed to an instance of the class, e.g.: Addition.getNumber1();.
You are almost there. You are missing 2 key points:
To share the variables number1, number2 and answer without instantiating the addIntegers class, you need to make them static.
To access the variables number1, number2 and answer from within the glue class' main method, you need to prefix the variables with the addIntegers class.
package christmas;
public class addintegers {
public static int number1 = 5;
public static int number2 = 10;
public static int answer;
public static int add2numbers(int a, int b) {
return (a+b);
}
}
package christmas;
public class glue {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(addintegers.add2numbers(addintegers.number1,addintegers.number2));
System.out.println(subtractintegers.sub2numbers(addintegers.number1,addintegers.number2));
addintegers.answer = (addintegers.add2numbers(addintegers.number1,addintegers.number2))+(subtractintegers.sub2numbers(addintegers.number1,addintegers.number2));
System.out.println("answer =" +addintegers.answer );
}
}
package com.rohov;
public class Application {
public static void main(String[] args) {
System.out.println(AddInteger.sum(AddInteger.num1, AddInteger.num2));
System.out.println(SubInteger.sub(AddInteger.num1, AddInteger.num2));
AddInteger.sum = AddInteger.sum(AddInteger.num1, AddInteger.num2) + SubInteger.sub(AddInteger.num1, AddInteger.num2);
System.out.println(AddInteger.sum);
}
}
class AddInteger {
public static int num1 = 5;
public static int num2 = 10;
public static int sum;
public static int sum(int a, int b) {
return a + b;
}
}
class SubInteger {
public static int sub(int a, int b) {
return a - b;
}
}
I have a superclass and one subclass with some variables like below:
public class A{
private int first;
private int second;
public A(int _first, int _second){
first = _first;
second = _second;
}
public int getFirst(){
return first;
}
}
public class B extends A{
private int third;
public B(int _first, int _second, int _third){
super(_first, _second);
third = _third;
}
public int getThird(){
return third;
}
}
I want to build a method in the main class that accepts a generic argument that can be of type A or type B like below:
public class Main{
public int val = 2;
public static void main(String []args){
A a = new A(1, 2);
B b = new B(1, 2, 3);
printObject(a);
printObject(b);
}
public void printObject(A a){
int f = a.getFirst() * val;
int s = a.getSecond() * val;
if(a instanceOf B){
int t = a.getThird() * val; // compiler does not find the getThird() method this way
}
}
}
How can this be achieved?. is generics an option? I have thought about making printObject() method inside A then override it inside B however I have some other variable like val above that I am creating in main.
update
I tried to use instanceOf like the above method. But this way the compiler does not find the subclass's specific method.
Firstly, by definition, if you declare A as a parameter to any method and B is it's sub-class, then any A or B can be passed to that method.
You could then achieve what you want using the instanceof operator (to check if the parameter passed in is of type B). However, inheritance / method override should typically be used rather than instanceof.
You could pass 'val' into the printObject() methods on A/B. If several variables like 'val' are involved you could pass in another object or perhaps you need to split your code across multiple methods on class A (overridden in B), passing in different values as appropriate? (You wouldn't normally do calculations in a method whose purpose is to print an object but perhaps that was just an example?)
Everything is much simplier) You could get rid of this method in the main class, cause it's producing some redundant coupling. And all this instanceof really smells in 2019. You could make it more independent.
Class A:
public class A{
private int first;
private int second;
public A(int _first, int _second){
first = _first;
second = _second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public void print(int multiplier) {
System.out.println(this.first * multiplier);
System.out.println(this.second * multiplier);
}
}
Class B:
public class B{
private int third;
public B(int _first, int _second, int _third){
super(_first, _second);
third = _third;
}
public int getThird(){
return this.third;
}
#Override
public void print(int multiplier) {
super.print(multiplier);
System.out.println(this.third * multiplier);
}
}
Class Main:
public class Main{
public int val = 2;
public static void main(String []args){
A a = new A(1, 2);
B b = new B(1, 2, 3);
a.print(val);
b.print(val);
}
}
Writing object oriented code is more than extending a class , your API's and other functionality should be designed as part of the solution.
In your case, the most appropriate way to do this is to add the print method to the object itself, you can either override the entire function or to call the super class inside the overriding class.
public class A{
/// ... your code
public void print(){
System.out.println("first :"+first+", second : "+second);
}
}
public class B extends A{
/// ... your code
public void print(){
//Option A - use parent class getters/setters to implement print for object B
System.out.println("first :"+super.getFirst()+", second : "+super.getsecond() +" third" + third);
}
//Option B (More usable to methods returning a value or performing an update) - Perform operation on parent variables, then perform on class specific variables
super.print()
System.out.println("third : "+third);
}
}
and then
A a = new A();
A b = new B();
a.print();
b.print();
Will each call the correct runtime function based on their actual implementation
Can someone explain why the function prints the variable from super and not from the subclass? Class variables cannot be overridden in Java?
class A {
int i = 1;
int fun() {
return i;
}
}
class B extends A {
int i = 2;
}
class Main {
public static void main(String[] args) {
System.out.println(new B().fun());
}
}
This prints out 1 instead of 2.
Because fields declared in the subclass never override fields of the super class.
Overriding is for methods.
If you want to use the i value of the current class, you could introduce getI() a method to provide the i value :
class A {
int i = 1;
int fun() {
return getI();
}
int getI(){
return i;
}
}
And override it in the subclass :
class B extends A {
int i = 2;
int getI(){
return i;
}
}
You are returning the value of i from fun() function . if you want to return the value of override variable from class B need to override that method, as fun method is a part of the super class it is referring i of super class only.
But always remember overriding of variable in java is always a bad idea it may give you unexpected result.
if you still want you can use this way.
class A {
int i = 1;
int fun() {
return i;
}
}
class B extends A {
int i = 2;
int fun() {
return i;
}
}
class Main {
public static void main(String[] args) {
System.out.println(new B().fun()); // this will refer the override i
}
}
Java 8
I was just a little perplexed by that we could not call virtual method from a constructor. The pitfall is that we can overload it and crash. But what if we call it from within a constructor of a final class. Like this:
public final class MyClass implements MyInterface {
private final Object[] arr;
public MyClass(){
Object[] arr;
//init arr
this.arr = arr;
//Now we have to preprocess it
preprocess();
}
#Override
public void preprocess(){
//impl
}
public int count(){
//impl
}
}
public interface MyInterface{
void preprocess();
int count();
}
Are there other pitfalls with calling virtual methods from within a constructor? Of course, I can extract preprocess into a static method and then call it from both, but it looks a little messy. I'd like to keep code as clean as possible.
You should always take care when calling methods from a constructor, because the object construction is not yet complete. This is true even for final and private methods, which cannot be overridden by subclasses.
Example:
public class Test {
public static void main(String[] args) {
new Sub().test();
}
}
class Base {
int b;
Base() {
test();
this.b = 1;
}
void test() {
System.out.println("Hello from Base. b = " + this.b);
}
}
class Sub extends Base {
int s;
Sub() {
test();
this.s = 2;
}
#Override
void test() {
System.out.println("Hello from Sub. b = " + this.b + ", s = " + this.s);
}
}
OUTPUT
Hello from Sub. b = 0, s = 0
Hello from Sub. b = 1, s = 0
Hello from Sub. b = 1, s = 2
test() is called 3 times: From Base constructor, from Sub constructor, and from main().
As you can see, even field b was not yet initialized on the first call.
So, is it illegal to do it? No.
Should you avoid it? Yes.
Just make it clear (e.g. javadoc) that the method may be called on partially initialized objects.
Ex
class A () {
class A(int a, int b) {
}
}
class B extends A {
int m;
int n;
class B()
{
getInput(); // i wanna invoke this method first before calling super(). But it does not allow in Java. How to work around this ?
super(m,n);
}
public void getInput() {
Scanner scanner = new Scanner(System.in);
m = scanner.nextInt();
n = scanner.nextInt();
}
public static void main () {
B b = new B();
}
}
You can force your super class to run a method at the beginning of its constructor and then override that method in the subclass. Many frameworks have a "setup" type method that you can override to accomplish such things.
public class A {
protected int a; // 'protected' so subclass can see it
protected int b;
public A() {
setup(); // Runs whatever setup method is implemented, even in subclasses
}
protected void setup() { /* nothing */ } // 'protected' to be overridden by subclass
}
public class B extends A {
public B()
{
super();
}
/**
* When A's constructor calls setup(), this method will run.
*/
#Override
protected void setup() {
Scanner scanner = new Scanner(System.in);
a = scanner.nextInt(); // Stores value in A's protected variable.
b = scanner.nextInt();
}
}
Depending on the specifics of the classes you're writing, this is where you might have multiple constructors, public or protected methods for setting values, etc. This is where Java is fairly flexible. As the comments below indicate, this isn't a very good practice in constructors, but I'd need more context to figure out how to accomplish what you're asking.
You could chain multiple constructors together as jbrookover alluded to in such a manner. Sligtly convoluted though:
class A () {
public A(int a, int b) {
}
}
class B extends A {
int m;
int n;
public B()
{
this(new Scanner(System.in));
}
private B(Scanner scanner) {
this(scanner.nextInt(),scanner.nextInt())
}
private B(int m, int n) {
super(m,n)
this.m = m;
this.n = n;
}
public static void main (String ... args) {
B b = new B();
}
}