is This Data Abstration Example right or not? - java

i had given the following code in an interview. I want to know whether it is right or not..
public class DataAbstraction
{
public static void main (String args[])
{
MyDetails obj = new MyDetails();
obj.setNumebr(10);
obj.incrementBy(20);
int num = obj.getMumber();
System.out.println(num);
}
}
class MyDetails
{
private int n;
public void setNumebr(int i)
{
n = i;
}
public void incrementBy(int i)
{
n = n + i;
}
public int getMumber()
{
return n;
}
}
So please check it and correct me if i was wrong

There are many forms of abstractions in software. I would say that this is an example of data abstraction (though I would usually call it encapsulation). You could, if you would like to, change the member variable n to be of type... String(!), without changing the public interface of MyDetails.
Put differently: The details in the MyDetails class are hidden from the client code. The fact that MyDetails stores an int is abstracted away and it could be changed, for instance like this:
class MyDetails
{
private String n; // changed internal detail
public void setNumebr(int i)
{
n = "" + i;
}
public void incrementBy(int i)
{
n = "" + getMumber() + i;
}
public int getMumber()
{
return Integer.parseInt(n);
}
}
Have a look at the Wikipedia article on data abstraction for further details:
Abstraction > Data abstraction

Since there aren't enough details in the question its guessing time again:
1) No, its wrong. it contains various spelling errors like "getMumber" and "setNumebr".
2) Yes, if we ignore the spelling errors the methods seem to do what one would expect from their names.
2) No, it doesn't launch the rocket and it doesn't scale to multi processor machines (assuming these where the requirements).

Related

When building containers why is using Java Generics better than using the Object Class? (Java Generics & DataStructures)

So I have been reviewing my data structures and came across an interesting thought regarding Java generics and the Object class. I have implemented and run a "generic bag" in two different ways (Notice below: IObjectBag.java, ObjectBag.java, IGenericBag.java, and GenericBag.java) and have used them both (Notice: Below main.java and Output). I have removed some of the unnecessary code as per stack overflow rules but if you want the full implementation, let me know.
Also, I have researched the topic in many websites, books and courses in addition to looking at the source code for the ArrayList class here and I understand that my GenericBag is a better option than my ObjectBag but not well enough to explain it in a practical way during an interview. And I am confused that my GenericBag uses more casting operations than my ObjectBag in its implementation (see Remove and PrintBag).
So, other than the syntactic sugar, why is my GenericBag better? Please use my classes as examples.
Are there any important differences in runtime/overhead/space/time I am not noticing?
How would you answer this question or expect it to be answered in an interview?
Bonus questions: If you want, please answer the bonus questions in the Main and GenericBag comments (I think I can answer them myself though, just want to hear your opinion).
IObjectBag interface:
public interface IObjectBag {
void add(Object item);
Object remove(Object item) throws NoSuchElementException;
boolean isEmpty();
int find(Object item);
Object get(int index);
int numItems();
}
ObjectBag class:
public class ObjectBag implements IObjectBag {
private Object [] items; // the java class attribute that will hold out "ints"
private int numItems;
public static void printBag(IObjectBag bag) {
for(int i = 0; i < bag.numItems(); i++) {
System.out.println(bag.get(i));
}
}
public ObjectBag(int size) {
this.items = new Object[size]; // fills array with null values
this.numItems = 0;
}
public void add(Object item){
// adds item to end of bag
}
public Object remove(Object item) {
int index = this.find(item);
if(index == -1) throw new NoSuchElementException("oops nothing found");
Object out = this.items[index];
this.items[index] = null;
this.numItems -= 1;
if(index + 1 != this.items.length && this.items[index + 1] != null) {
for(int i = index; i < this.items.length; i++) {
if(i + 1 != this.items.length) this.items[i] = this.items[i + 1];
}
this.items[this.items.length - 1] = null;
}
return out;
}
public int find(Object item) {
// return index given item or -1
}
public Object get(int index) {
// returns item given index
}
}
IGenericBag class:
public interface IGenericBag <T> {
void add(T item);
T remove(T item) throws NoSuchElementException;
boolean isEmpty();
int find(T item);
T get(int index);
}
GenericBag class:
public class GenericBag<T> implements IGenericBag<T> {
// private T[] items; can't use this b/c see comment in constructor
private Object[] items;
private int numItems;
public static void printBag(GenericBag bag) {
for(int i = 0; i < bag.numItems(); i++) {
System.out.println(bag.get(i));
}
}
public GenericBag(int size) {
// this.items = new T[size]; Bonus: throws generic array creation error (why?)
this.items = new Object[size];
this.numItems = 0;
}
public void add(T item){
this.items[this.numItems] = item;
this.numItems += 1;
}
public T remove(T item) {
int index = this.find(item);
if(index == -1) throw new NoSuchElementException("oops nothing found");
T out = (T) this.items[index];
this.items[index] = null;
this.numItems -= 1;
if(index + 1 != this.items.length && this.items[index + 1] != null) {
for(int i = index; i < this.items.length; i++) {
if(i + 1 != this.items.length) this.items[i] = this.items[i + 1];
}
this.items[this.items.length - 1] = null;
}
return out;
}
public int find(Object item) {
// given object return index or throw exception
}
public T get(int index) {
return (T) this.items[index];
}
}
Main class:
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello StackOverFlow!");
Object int1 = new Integer(1);
Object int2 = new Integer(2);
Object int3 = new Integer(3);
/* using my object bag ************************************************/
System.out.println("using my object bag");
IObjectBag myObjectBag = new ObjectBag(3);
myObjectBag.add(int1);
myObjectBag.add(int2);
myObjectBag.add(int3);
myObjectBag.remove(int2);
ObjectBag.printBag(myObjectBag);
/* using my generic bag ***********************************************/
System.out.println("using generic bag");
// Bonus Question: using object like above causes error at add method (why?)
Integer int4 = new Integer(4);
Integer int5 = new Integer(5);
Integer int6 = new Integer(6);
GenericBag<Integer> myGenericBag = new GenericBag<Integer>(3);
//Bonus Question: using Interface decllaration like above causes error in print bag (why?)
myGenericBag.add(int4);
myGenericBag.add(int5);
myGenericBag.add(int6);
myGenericBag.remove(int4);
GenericBag.printBag(myGenericBag);
}
}
Output:
Hello StackOverFlow!
using my object bag
1
3
using generic bag
5
6
Problems with your ObjectBag that are 'automaticaly' solved by the type safety offered by your GenericBag implementation:
Accessing an entry returns Object, at this stage you do not know of what type Object is.
You can insert any types of Objects (mixed) e.g a String and an Integer into the same list, this is an anti pattern and causes non readable code (try it with your Generics bag!)
Because your compiler knows the type of your GenericBag after you have declared it, at any stage of your code if you hover over your genericBag instance you will know its type, this makes your code more readable and also extendable for other people
Generics also offer way more, imagine you want your GenericBag to only accept numbers, then you could write it as follows:
public class GenericBag<T extends Number>
My suggestion for you is to read some articles on Java basics and especially Generics, having a praxis based way of learning is a good thing, but there are plenty articles that can give you some very nice theoretical insight on the matter.
https://www.baeldung.com/java-generics
Reason of using, let's say, GenericBag<String> over ObjectBag is essentially the same as for using String (or any other type) over an Object:
Type safety.
You declare that some method returns a collection of Strings and nothing else, thus preventing yourself from putting there other objects, or trying to treat what you get from a bag as some other type. This might sound stupid when you have 100 lines of code, but this may save you lot of debugging time when you work with decent codebase.
Although, type safety is not a silver bullet, it is just an instrument, that some people find useful and some don't. I'm pretty sure it is a popular holywar topic for any programming forum.
If you feel comfortable working without this paradigm (Javascript background, right?), you might consider trying some dynamically typed language like Python instead of Java.

Setting a value to zero

Ok so in my cs class we have an assignment that requires us to return a value and then set it to zero. I can't figure out how to do this without using a secondary variable(which would break requirements) so I would appreciate some help. here are the exact requirements.
"Has a use() method that returns the value contained in the points field. It also resets the points field to zero. You’re going to have to think about the order of operations here to make this work correctly."
package Game;
import java.util.Random;
public class HealthPotion
{
private int points;
boolean Haspotion;
HealthPotion()
{
Random num1 = new Random();
int num = num1.nextInt(10)+1;
points=num*10;
}
public int Use()
{
return points;
}
public int getPoints()
{
return points;
}
}
That's not really possible without abusing a finally block, i.e.
try {
return points;
} finally {
points = 0;
}
However it's really hard to believe that would be what's wanted, since it's not a good idea to write code like that.
Include a setter method like this.
public void setValue(){
this.points=0;
}
Call this method after you get the value.
How about this?
public int Use()
{
int tmp = points;
points = 0;
return tmp;
}
It has limitations, especially if points can be changed by a different thread while this method executes. But if you are working in a single-threaded environment this should be ok.
This should work
int points = 5;
public void test(){
System.out.println(use() +" " + points);
}
private int use(){
return points - (points = 0);
}
returning 5 0

Am I returning the correct value from my method & am I writing it correctly?

I'll preface my question with the statement that I am very new to Java, so I apologise if my code is totally disgusting to read.
What I'm trying to do: I'm writing a program that takes two integers from the user, a low value and a high value, and sends both integers to two different methods. Method #1 has a simple for loop and should print out all of the numbers between the lowest number and the highest number that are multiples of 3 or 5, and Method #2 does the same except for numbers that are multiples of 3 or 5 it also checks if that number is also a multiple of 6 and, if so, it prints the number and an asterisk next to it.
What I'm having trouble with: I'm pretty stumped on what I need to return from my methods & how to return anything at all. This is the first time I've worked on a method properly (just moved up from "Hello World) and from what I can see I don't really need to return anything at all. All the code that I've put in my methods pretty much complete the program, so I thought maybe returning the integers I sent would be enough, apparently it's not. So, without further ado, here's my code.
The Error:
javac BonusQ.java
.\MethodOne.java:19: error: illegal start of type
return(int lowestRange, int highestRange);
^
.\MethodTwo.java:36: error: illegal start of type
return(int lowestRange, int highestRange);
^
The Main:
import java.util.Scanner;
public class BonusQ
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int lowestRange = 0;
int highestRange = 0;
System.out.println("Enter the lowest integer in your range");
lowestRange = scan.nextInt();
System.out.println("Enter the highest integer in your range");
highestRange = scan.nextInt();
MethodOne.NoAsterisk(lowestRange, highestRange);
MethodTwo.Asterisk(lowestRange, highestRange);
}
}
MethodOne:
public class MethodOne
{
public static int NoAsterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
System.out.println(i);
}
else if (i%3 == 0)
{
System.out.println(i);
}
}
}
return(int lowestRange, int highestRange);
}
MethodTwo:
public class MethodTwo
{
public static int Asterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
if (i%5 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
else if (i%3 == 0)
{
if (i%3 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
}
}
return(int lowestRange, int highestRange);
}
Sorry if the post is a bit beefy to read, I just find that adding my thoughts on the code might help you explain to me what's going wrong, seeing as you may not know the extent of my incompetence :)
Thanks in advance.
Ok, Classes have members.
Members are either some variables or arrays of variables
and the methods of a class.
So you got
public class MyMethod
{
public static int Asterisk(int loRange, int hiRange)
{
// Do magic let's make a sum for this example
// You enter loRange and hiRange (you defined it above)
return loRange + hiRange // Here the method returns a result
}
}
// So then....
public static void main(String [] args)
{
// WHATEVER IS IN HERE RUNS ALWAYS FIRST.
z = Asterisk(1,2); // 1 and 2 is lo and hi range values ;)
// Z has a value of 3 now because Asterisk(1,2) returns 1 + 2
}
See how this works?
Now this works because you use the static definition (meaning there must not be an instance of MyMethod created first to use the method. It's not wrong, but if you can make a program do things with class instances, you better do it that way.
You make an instance of a class, this is called an object, using a special method. This method has the exact name of the Class and constructs an instance of it.
You should study now about constructors, abstract classes etc etc.
I can't say you do it wrong or right either. It is about what the program is all about and you should study the scope for variables and methods, and the encapsulation concept of Object Oriented Programming.
Using only static methods, goes against encapsulation principle, it is possibly wrong but I can't tell for sure.
I hope this helped you and gave you a good direction to go on with your study.
PS:
To return multiple results, you should return an array of variables, not just a variable.
You can also return nothing and just have it do the job to a needed array. This FORCES you though to make this array public. (Not a good practice)
Finally if multiple value returns are needed to just print them on the console... well, just do it in the method, no need to return anything really.
You don't need to return anything, being that the methods are printing out all the values.
You can change them into void methods, for example:
public static void asterisk(int lowest, int highest) {
//loops and if statements
//no return statement!
}
The code in the methods will run and voila, you are done!
EDIT: That being said, there's a lot more than can be done to make this code more Java-like, but for now this will work.
mmmmm...you can return types, and (int lowestRange, int highestRange) its not a type. Look at the method definition
public static int Asterisk(int lowestRange, int highestRange)
the return type is declared as int, so you should return an int value. You can do something like
return lowestRange;
return 1;
with that in consideration, the error should dissapear. The question is, why do you need to return a value? From what i've read, your methods are supose to print stuff, not to return stuff...
The return statements are out of the method. You have to put them before the close method brackets.
public class MyClass{
public int sum (int a, int b){
return a + b;
} // The return have to be before this brackets
}

Good practice in using properties and local variables

Is it a good practice to use properties as local variable. In cases where there are many methods which uses some variables, In each method the variable value changes. This avoids many times creating new variables and the code increases. Any suggestion?
private void method1(){
int totalLength = length1 + 10;
int totalBreath = (breath1 + breath2) + 20;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method2(){
int totalLength = length1 + 20;
int totalBreath = (breath1 + breath2) + 30;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method3(){
int totalLength = length1 + 60;
int totalBreath = (breath1 + breath2) + 10;
int size = (totalLength * totalLength);
System.out.println(size);
}
As you can see, totalLength, totalBreath, size is repeated in every method. Can i make them as fields of the class? So, i need not declare it in every method.
private void method1(){
totalLength = length1 + 10;
totalBreath = (breath1 + breath2) + 20;
size = (totalLength * totalLength);
System.out.println(size);
}
I read your question as, "When should a local variable be promoted to be a field of the class?"
The best answer is "it depends" but then again, its accuracy is quickly eclipsed by its lack of usefullness.
Fields should have a relationship to the class itself, as in is the field an attribute of the class? I include an example below to illustrate the syntax difference, but I agree with this post that it should be avoided if it pollutes the meaning of the class.
Usually you only need to have a field when you need the value of the field to be maintained between calls to different methods for a given instance of the class, with the option of making it static when the value should be maintained between method calls for all instances of the class. It will depend on several factors like shop convensions, performance goals, existing codebase, etc. so there is no single right answer without specific code. This question seems to include similar points. If you find yourself using the approach below, you might consider other approaches like refactor the behavior into a help class.
Another question asks the same question but from the perspective of a programming student.
Examples:
public class VariableScope {
int field1 = 3;
void foo() {
int a = 2;
// variable passing in width
bar1(1);
bar2(1);
// variable passing in depth
bar3(a);
// uses a field to reduce variable passing
baz1();
baz2();
}
void bar1(int param) {
System.out.println("param=" + param);
}
void bar2(int param) {
System.out.println("param=" + param);
}
void bar3(int param)
{
System.out.println("Passing param to bar4");
bar4(param);
}
void bar4(int param){
System.out.println("param=" + param);
}
void baz1() {
System.out.print("field1=" + field1);
}
void baz2() {
System.out.print("field1=" + field1);
}
}
From what it sounds like, if you're using the variable for multiple methods you're should declare the variable as a global variable. But yes, If no other method needs that variable , and you don't want to be writing a bunch of return statements you can use local variables
I suppose you mean a field by property which usually has accessor and mutator (get,set-methods).
In common you should keep the scope of a variable as small as possible. An example if you use many for loops like:
for ( int i = 0 ; i < 10 ; i++ ) {
}
and replace this by
int i;
method1() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
method2() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
If one thread calls method1() and another one method2() you would face a race condititon.
You can easily introduce hard to find bugs in your code.
I assume you mean something like this:
Class foo() {
int x;
public bar() {
for(x = 0; x <100; ++x) ...
} }
No, it's not good practice.
One place where it can even be harmful is in the synchronization/concurrency/multi-threaded case: if you are working with class members, they are going to need be synchronized which will eat into performance. Otherwise you risk multiple threads overwriting the value of the field and that can lead to errors in your program (likely hard to debug).

Interesting issue about java and linking "&"

I know that there isn't way to access to the links of variables in java (like in &C or &php). But for example I have such task:
public class JustTest {
private int n = 1;
private int x = 10;
public int[] getIntegers() {
return new int[] { n, x };
}
public void filledInteger() {
int[] vals = getIntegers();
System.out.println("Before change");
System.out.println(Arrays.toString(vals));
vals[0] = 2;
vals[1] = 20;
System.out.println("After change");
System.out.println(Arrays.toString(vals));
System.out.println("Values of name & xml");
System.out.println(n);
System.out.println(x);
System.out.println("calling getIntegers");
System.out.println(Arrays.toString(getIntegers()));
}
public static void main(String[] args) {
JustTest t = new JustTest();
t.filledInteger();
}
}
The result is:
Before change
[1, 10]
After change
[2, 20]
Values of name & xml
1
10
calling getIntegers
[1, 10]
So, I want to change values of "n" and "x" fields of the class instance. I can't do this by setting straightly (this->n = 20;), because I may dont know what fields do I have. Only method getIntegers knows.
(No in this code, but for example I have child class with its own fields and in the parent class I have a method filledInteger() which should change specified properties of the child class ( he knows about this properties from the method getIntegers which is abstract in the parent class and implemented in the child class))
Here is simple implementation (without inheritance), using links in php
<?php
class JustTest {
private $n = 1;
private $x = 10;
public function getIntegers() {
return array( &$this->n, &$this->x );
}
public function filledInteger() {
$vals = $this->getIntegers();
echo("Before change" . "<br/>");
echo(print_r($vals, true) . "<br/>");
$vals[0] = 2;
$vals[1] = 20;
echo("After change" . "<br/>");
echo(print_r($vals, true) . "<br/>");
echo("Values of n & x". "<br/>");
echo $this->n , "<br/>";
echo $this->x , "<br/>";
echo("call getIntegers again" . "<br/>");
echo(print_r($this->getIntegers(), true) . "<br/>");
}
}
$t = new JustTest();
$t->filledInteger();
?>
The result is:
Before change
Array ( [0] => 1 [1] => 10 )
After change
Array ( [0] => 2 [1] => 20 )
Values of n & x
2
20
call getIntegers again
Array ( [0] => 2 [1] => 20 )
That is what I exactly need. Im just curious how do I implement this in java
Hope you understood.
Next example:
public abstract class ParentTest {
abstract int[] getIntegers();
public void fillIntegers(int[] newIntegers) {
int[] integersOfChild = getIntegers();
for (int i = 0; i < integersOfChild.length; i++) {
integersOfChild[i] = newIntegers[i];
}
}
}
public class ChildTest extends ParentTest {
private int x;
private int y;
#Override
int[] getIntegers() {
return new int[] {x, y};
}
}
public class UseTest {
void main() {
List<ParentTest> list;
for (ParentTest item : list) {
item.fillIntegers(myItegers);
}
}
}
This is what I need. I have a list of ParentTest instances (it may be ChildTest, or ChildTest2, or ChildTest3; but they all children of a ParentTest) and I need to fill all fields with my integer values, but I dont know if items in the list instances of a ChildTest, or ChildTest2, or ChildTest3 class
How do I implement this in Java?
With great pain via the Reflection API. If you want to write code like this, the best idea is to use another language.
Consider programming in Groovy instead. You can use array syntax to directly access class members by name: t["n"] = 2; This works with legacy Java code, so there is no need to modify TestClass to support this usage.
The concept you are talking about is called pass by reference. Java has for the most part abandoned it - it creates too many side-effects, like the one you are seeing here.
The issue is that while unfortunately you can't do this here, it actually prevents a huge number of unintentional bugs being released.
What about something like that:
public final class JustTest {
private final Map<String, Object> fields;
public void filledInteger() {
System.out.println("Before change\n" + this.fields);
fields.put("N", 2);
fields.put("X", 20);
System.out.println("After change\n" + this.fields);
System.out.println("Values of name & xml\n" + fields.get("N")
+ "\n" + fields.get("X"));
}
private JustTest() {
this.fields = Maps.newHashMap(); // guava
fields.put("N", 1);
fields.put("X", 10);
}
public static void main(String[] args) {
final JustTest t = new JustTest();
t.filledInteger();
}
}
You can't do individual fields without reflection, but you can change the contents of collections. Note that this is not really intended behavior, but rather something you have to be careful of when using collections.
This outputs 5 3 2 4 2 4
public class Test
{
public Vector<Integer> args = new Vector<Integer>();
public void fillArgs()
{
args.add(5);
args.add(3);
}
public Vector<Integer> getArgs()
{
return args;
}
public static void main(String args[])
{
Test s = new Test();
s.fillArgs();
Vector<Integer> temp = s.getArgs();
for (Integer i : temp)
System.out.println(i);
temp.setElementAt(2, 0);
temp.setElementAt(4, 1);
for (Integer i : temp)
System.out.println(i);
for (Integer i : s.getArgs())
System.out.println(i);
}
}
Your php example does not return an array of ints, but rather an array of int pointers. This is NOT something you can do in Java, in fact, this is NOT something you want to do in Java. Give a use case, and there is likely a better way to solve the problem you have.
If you want to return an object that others can affect and that are contained as member variables, do that. An ArrayList, HashMap, etc... there are plenty of things that can fit your needs. If you are given someone elses class and you must stick your nose in their code, you can get around their private declaration doing the following:
public void setN(JustTest j, int n) {
//You would handle some exceptions here also
Field f = JustTest.class.getDeclaredField("n");
f.setInt(j, n);
}

Categories