Executed Python code:
class Test(object):
item = 0
def __init__(self):
print(self.item)
def test(self):
print(self.item)
class Subclass(Test):
item = 1
s = Subclass()
s.test()
gives:
1
1
Executed analogical Java code:
public class Test {
int item = 0;
Test(){
System.out.println(this.item);
}
void test(){
System.out.println(this.item);
}
public static void main(String[] args){
Subclass s = new Subclass();
s.test();
}
}
class Subclass extends Test {
int item = 1;
}
gives:
0
0
Apparently, Java method inherited from base class (Test) uses also base class' member variables. Python method uses the member variable of derived class (Subclass).
The question: Is there any way to achieve the same or at least similar behaviour in Java like in Python?
Objects in Python are pretty much just like Dictionaries in Python. You can think of each instance of Test and Subclass as a Dictionary that is updated by the __init__ code and assignments in the body of the class you declare. You can picture the code you wrote working something like this:
class Test(object):
item = 0 # self['item'] = 0
def __init__(self):
print(self.item) # print(self['item'])
def test(self):
print(self.item) # print(self['item'])
class Subclass(Test):
item = 1 # self['item'] = 1
s = Subclass() # Test.__init__({})
s.test()
Python uses duck-typing, so item is just some property of whatever you happen to have an instance of. Notice that you don't ever actually have to declare item—you just assign a value. This is why you're able to "override" the value in the sub-class—because you're actually just overwriting the old value of the same field. So in the example you gave, the item in Subclass isn't actually overriding the item in Test; rather, they are the same field in a Python object instance.
In Java fields actually belong to specific classes. Notice how in your code you actually have two declarations of the field int item: one in Test and one in Subclass. When you re-declare the int item in Subclass you are actually shadowing the original field. See Java in a Nutshell: 3.4.5. Shadowing Superclass Fields for more info.
I'm not sure exactly what you're trying to do with your example, but this is a more idiomatic Java approach:
public class Test {
private int item;
public Test() {
this(0); // Default to 0
}
public Test(int item) {
setItem(item);
test();
}
public void test() {
System.out.println(getItem());
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.test();
}
public void setItem(int item) {
this.item = item;
}
public int getItem() {
return item;
}
}
class Subclass extends Test {
public Subclass() {
super(1); // Default to 1
}
}
Notice how the value of item is set via a constructor argument rather than by simple assignment. Also notice how item is private and that there is now a getter and setter method to access it. This is more Java-style encapsulation.
That seems like a lot of code, but a good IDE (such as Eclipse or IntelliJ) will auto-generate a lot of it for you. I still think it's a lot of boiler-plate though, which is why I prefer Scala—but that's a whole different discussion.
Edit:
My post grew so long that I lost track of why I wanted to introduce getters and setters. The point is that by encapsulating access to the field you're able to do something more like what you had in Python:
public class Test {
// Same as above . . .
}
class Subclass extends Test {
private int subclassItem = 1;
public int getItem() {
return subclassItem;
}
public void setItem(int item) {
this.subclassItem = item;
}
}
Now the item field has effectively been overridden since all access to it is done through the getter and setter, and those have been overridden to point at the new field. However, this still results in 0 1 in the output rather than the 1 1 you were expecting.
This odd behavior stems from the fact that you're printing from within the constructor—meaning the object hasn't actually been fully initialized yet. This is especially dangerous if a this reference is passed outside the constructor during construction because it can result in outside code accessing an incomplete object.
You could overload the superclass constructor to initialise the field item in Test to 0:
public class Test {
int item = 0;
Test(){
System.out.println(this.item);
}
Test(int item) {
this.item = item;
System.out.println(this.item);
}
void test(){
System.out.println(this.item);
}
public static void main(String[] args){
Subclass s = new Subclass();
s.test();
}
}
class Subclass extends Test {
public Subclass() {
super(1);
}
}
Use an initializer instead of redeclaring the fields:
public class Test {
int item = 0;
...
}
public class Subclass extends Test {
{
item = 1;
}
}
Note: depending on your package structure, you might want to declare item as protected.
Related
I wrote this simple class in java just for testing some of its features.
public class class1 {
public static Integer value=0;
public class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output is:
2
But in this code:
public class class1 {
public static Integer value=0;
public void class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output of this code is:
0
So why doesn't, when I use void in the constructor method declaration, the static field of the class doesn't change any more?
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a void. Note the difference here:
public class SomeClass {
public SomeClass() {
//constructor
}
public void SomeClass() {
//a method, NOT a constructor
}
}
Also, if a class doesn't define a constructor, then the compiler will automatically add a default constructor for you.
public void class1() is not a constructor, it is a void method whose name happens to match the class name. It is never called. Instead java creates a default constructor (since you have not created one), which does nothing.
Using void in the constructor by definition leads it to not longer be the constructor.
The constructor specifically has no return type. While void doesn't return a value in the strictest sense of the word, it is still considered a return type.
In the second example (where you use the void), you would have to do h.class1() for the method to get called because it is no longer the constructor. Or you could just remove the void.
This is arguably a design flaw in Java.
class MyClass {
// this is a constructor
MyClass() {...}
// this is an instance method
void MyClass() {...}
}
Perfectly legal. Probably shouldn't be, but is.
In your example, class1() is never getting called, because it's not a constructor. Instead, the default constructor is getting called.
Suggestion: familiarize yourself with Java naming conventions. Class names should start with uppercase.
The reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the run time.
Here is an article explaining this in greater detail:
https://www.quora.com/Why-is-the-return-type-of-constructor-not-void-while-the-return-type-of-a-function-can-be-void
How do I access the property of a child class instead of the abstract class, when handling objects by their parent/abstract class? Like in this example:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
// ...
}
}
/* ... then we build a collection with members like: */
nouns.add(new WordCategories.Person("Bill Clinton");
/* now later we need to access a mixed list of nouns: */
for(WordCategories.Noun n: nouns) {
if(n.TYPE.equals("Person") ){ // this is always null
}
Obviously I could just specify (WordCategories.Person) n but that assumes that it is a Person. I need the cast to come from the parent class, and it would be most elegant if it did not involve interpreting the TYPE constant or the use of reflection, for that matter.
You don't have to use reflection at all. If you understand what type it is you like, you can use instanceof to get the specific class instance you care about.
for(WordCategories.Noun n: nouns) {
if(n instanceof WordCategories.Person) {
// cast to WordCategories.Person and perform whatever action you like
WordCategoriesPerson actualPerson = (WordCategories.Person) n;
}
}
This trumps the usage of the field to determine the object type, since the class contains enough metadata for you to want to use in this scenario. While many people would also discourage the use of instanceof due to performance (and frankly, if you wanted a list containing WordCategories.Person, just ask for one), its use in this instance would be cleaner than forcing each child class of WordCategories.Noun to create a method to inform us of what type it is.
static fields are always looked up by static type, so it doesn't matter what you assign to n; n.TYPE will always be WordCategories.Noun.TYPE. Heck, n could even be null:
System.out.println(((WordCategories.Noun) null).TYPE); // Doesn't cause an exception.
There is no way to get n.TYPE to behave the way you want with a static TYPE field. You will need to either make it non-static (and make all your objects bigger in the process), or you will need to change the way you access this data.
Instead of trying to access this through a static field, I recommend using an instance method:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
public abstract String getType();
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
public String getType() {
return TYPE;
}
// ...
}
}
...
for(WordCategories.Noun n: nouns) {
if(n.getType().equals("Person") ){
...
}
}
Try the test case:
public static void main(String[] args) {
Base sub1 = new Sub();
System.out.println(sub1.TYPE); // will print 'BASE'
Sub sub2 = new Sub();
System.out.println(sub2.TYPE); // will print 'SUB'
}
static class Base {
static String TYPE = "BASE";
}
static class Sub extends Base {
static String TYPE = "SUB";
}
If you access static field by the instance, it is decided by instance's declare Class, not the instance's real Class.
In your code for(WordCategories.Noun n: nouns) {, n's declare Class is Noun,so whatever n's real Class is,n.TYPE will only be null.
So, either use directly Class to access static fields, or use non-static field or method. Your usage is not wise, you should just take a different way.
Maybe you just need a non-static method:
public String getType() {
return TYPE;
}
I have some problems using this keyword. If I have a couple of classes implementing another class, how can I use their values without calling the class itself? I explain.
//this is my first class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
//getter/setter below
}
//this is my second class
public class Foo2 extends FooHelper{
public double fooDouble;
public float fooFloat;
}
//this is my main method, i'm using it for calling the value.
//I omit all the thrash code before.
//This is how i want to call the method:
//imagine before there are onCreate, activity,...
Foo foo = new Foo().GetFooInt();
//this is the class extended from the firsts
public class FooHelper{
public void GetFooInt(){
//here is my problem, i need to call the Foo class and the fooInt value.
//I want also to be able to edit the Foo object, for example:
if(((Foo)this).getFooInt() == 0){
(Foo) this.setFooInt(5);
}
}
}
This is what i want to achieve, acces a class which extends another class with the only this keyword from the extended class. How can I do it?
EDIT:
I badly explained i think.
My problem is that i want to access my Foo object inside the FooHelper, not FooHelper's method inside Foo object.
Example:
after using this code:
Foo foo = new Foo();
foo.HelperClassMethod();
I need (in HelperClass) to access Foo object which invoked it.
public HelperClass<Foo> {
public void HelperClassMethod(){
//HERE i need to use the "foo" object which invoked this method
}
}
I added the <Foo>, probably I was missing it, is this correct? and how can i use this foo object in the method from the helper class? thanks all
EDIT2: i totally failed on my question i thinkm lets ignore the above code and just check below:
I Have to access an object inside the extended class's method.
I have this class:
public class Foo extends FooToExtend{
public int fooInt;
}
the class which is extended is this:
public class FooToExtend{
public void MethodOne(){
//HERE i need to access the calling object
}
}
now, in my main activity, I want to do this:
Foo foo = new Foo();
foo.MethodOne();
My doubt is how i can access foo object i created in main inside my MethodOne.
I have to change my FooToExtend in
public class<Foo> FooToExtend{
...
}
but I don't still know how to access the foo object inside it.
I see 2 problems here, understanding this keyword, and extending clases
PROBLEMS WITH this KEYWORD
Imagine you have a class and you are executing some code: keyword this refers to the class itself, if you where the object this would be the equivalent to me. Check here and here longer explanations, examples and tutorials.
PROBLEMS WITH extend
Also you must extend from top (interfaces or abstract classes) to bottom (extended) classes and implement in bottom part:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
public abstract class FooHelper{
public abstract void GetFooInt();
}
//this is the CHILD (SECOND!!!) class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
#Override
public void GetFooInt() {
// are you sure you getFooInt method can return a null???
if(this.getFooInt() == null){
this.setFooInt(5);
}
//getter/setter below
}
EDIT 1
Oh ok, this was useful. one more question, a way is to use abstract, as you said, but is there a way to do the same without implementing it all times? just for info, my objective is to use Foo.FooHelperMethod() and be able in "FooHelperMethod()" to access Foo class. I hope i explained it, i don't know how to do it.. if it's impossible i will use abstract as you suggested :)
Sure, this is inheritance, simply don't declare abstract the parent, and implement the methods AND the attributes there, all the children will have this methods and attributes by extending the parent class.
Lets see this example:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
class FooHelper {
int theIntCommonValue;
public int getTheIntCommonValue() {
return theIntCommonValue;
}
public void setTheIntCommonValue(int theIntCommonValue) {
this.theIntCommonValue = theIntCommonValue;
}
}
// CHILDREN CLASS, look how calling this.getTheIntCommonValue() (the parent method)
// doesn't throw any error because is taking parent method implementation
class Foo extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 0)
this.setTheIntCommonValue(5);
}
}
class Foo2 extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 3)
this.setTheIntCommonValue(8);
}
}
EDIT2:
My doubt is how i can access foo object i created in main inside my MethodOne.
ANSWER:
Passing the object as a parameter. But then, you need static class, not an extended one, lets see an
EXAMPLE:
Foo.java
public class Foo {
public int fooInt;
}
FooHelper.java
public static class FooHelper {
public static void methodOne(Foo foo){
//HERE i need to access the calling object
// for example, this?
if (foo.fooInt == 2)
}
}
Now, how do you execute it?
Main.java
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
FooHelper.methodOne(foo);
}
NOTES
conventions say, methods in java start in LOWECASE and class name starts in UPPERCASE.
you must put both classes in sepparated files in order to allow static public class
I'm not sure I completely understand. But it looks as though you want GetFooInt to perform something differently depending on the class that extended it. So I think the best here to check the instanceof.
public class FooHelper{
public void GetFooInt(){
if(this instanceof Foo)
{
((Foo) this).fooInt = 5;
}
}
}
By the situation you want to named one class "Helper" I assume you will use it as a helper-class.
public class Helper {
public static int screenHeight = 500;
}
public class AnyOtherClass {
testSomething() {
System.out.println(Helper.screenHeight);
Helper.screenHeight = 510;
System.out.println(Helper.screenHeight);
}
}
For some basic understanding: this is the keyword you use in a non-static context to access the variables and methods of the Object you're currently inside. Proper use of this example:
public class SomeClass {
private int someInt;
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
}
In this example the this is necessary because the local variable (/parameter) someInt has the same name as the global class variable someInt. With this you access the class varaible of the Object you're "in".
Example of unnecessary use of this:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return this.someInt * this.someInt;
}
}
Here you don't need the keyword this since there is no local variable called someInt.
On the other hand super is a keyword which accesses the variables and methods of the parent class (the class, your class is derrived from). Example:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return someInt * someInt;
}
}
the derrived class:
public class Other extends SomeClass {
public int squarePlusSquare() {
return super.squareSomeInt() + super.squareSomeInt();
}
}
This may seem a basic question, but I'd like to get this right.
I have a Class 'AWorld'. Within that class, I have a method that draws a border, depending on the map size set by the user.
If the variable 'mapSize' is private, but I want to access it's value from within the same class, is it more appropriate to reference it directly, or use a getter method.
The code below should explain what I'm wanting to know.
package javaFX;
public class AWorld {
//initialized later
AWorld newWorld;
private int mapSize = 20;
public int getMapSize()
{
return mapSize;
}
public void someMethod()
{
int var = newWorld.mapSize; //Do I reference 'mapSize' using this...
}
// Or...
public void someOtherMethod()
{
int var = newWorld.getMapSize(); //Or this?
}
public static void main(String[] args) {}
}
Either of those is ok since you're getting a primitive field. If the get method does another operation before returning the data e.g. performing a math operation on the value, then it would be better to use it rather than calling the field directly. This is specially meant when using proxy/decorator pattern on your classes.
Here's an example of the second statement from above:
//base class to be decorated
abstract class Foo {
private int x;
protected Foo foo;
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
public Foo getFoo() { return this.foo; }
//method to prove the difference between using getter and simple value
public final void printInternalX() {
if (foo != null) {
System.out.println(foo.x);
System.out.println(foo.getX());
}
}
}
//specific class implementation to be decorated
class Bar extends Foo {
#Override
public int getX() {
return super.getX() * 10;
}
}
//decorator
class Baz extends Foo {
public Baz(Foo foo) {
this.foo = foo;
}
}
public class Main {
public static void main(String[] args) {
Foo foo1 = new Bar();
foo1.setX(10);
Foo foo2 = new Bar(foo1);
//here you see the difference
foo2.printInternalX();
}
}
Output:
10
100
You better dereference it directly.
The point of the private modifier is not to expose internal implementation to other classes. These other classes will use the getter method to get the value of the private property.
In your own class, there is no point on using the getter. Worse, someone may have overridden that method in a class that extends your class, and the getter may perform something that you do not expect
IMHO, if you are referencing a field of the current instance the general rule is to access the field directly with mapSize or this.mapSize.
If you are referencing a value from a different instance (be it of the same class or a different class, I would use the getter method). I believe this would lead to simpler refactoring. It also maintains the contract that any other instance gets the field value via the getter which allows for additional functionality in the getter.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Within my main method I'm trying to understand how to call up a variable from a different class.
I've attempted to break it down to the most simple solution possible just so I can get my head around the logic involved.
I have two classes within my package "var":
Class 1 - Source.java
package var;
public class Source {
int source1;
class setSource{
int source1 = 5;
}
}
Class 2 - Var.java
package var;
public class Var {
public static void main(String[] args) {
int Var;
Var = Source.setSource();
}
}
First time post here but I've spent 4 days and almost all my spare time trying to figure this out, please be gentle I'm dedicated but extremely newbie right now. Thanks in advance, I hope I've submitted this correctly.
Okay, I can sort of see what you were thinking but you've got some of the semantics incorrect. What you want to define is a method. A method takes the following structure:
<access modifier> <return type> <method name> (<method arguments>)
So for example
public void doSomething(String value) {
// This is the public method that returns nothing. It is called doSomething
// It expects a string value that it will call "value"
}
In your case, you want to create one of these, and you want to make a setter and a getter (or accessor and mutator if you're being posh).
Your Setter
This is just a normal method. Its purpose is to set the value of some class field. So let's define our class..
public class MyClass {
private int num;
}
Now we've got a class MyClass with a field num. But oh no, it's private, so let's create a setter so that the user can update the value.. Following our formula for methods, we start with a public access modifier. We then define the return type, which is void because it returns nothing. The name of the method should follow the java naming convention, which is the word "set" followed by the name of the member and finally the value for the setter.. Or all together:
public void setNum(int num) {
this.num = num;
}
This will update the value in the class with the value that you pass in. Excellent!
Your Getter
Well, this is nice and simple. Following our formula, it is a method that is public because everyone can access it; it returns something (in this case int) so that is the return type; the name follows the convention of "get" followed by the name and it expects no parameters.
public int getNum() {
return num;
}
This will return the value of num.
Finally, Using them!
public class MainClass {
public static void main(String[] args) {
MyClass myClass = new MyClass();
// Create a new MyClass instance.
myClass.setNum(4);
// Update the value in the class with the number 4.
System.out.println("The number is " + myClass.getNum());
// Outputs: "The number is 4"
}
}
you are using static calls, so you have to set this variables public static :
public static int source1;
and access them directly:
Var = Source.source1;
Your concepts are not well polished.
Your classes should have been like this
public class Source {
private int source;
public void setSource(int src){ // Called setter
source = src;
}
public int getSource(){ // Called getter
return source;
}
}
And
public class Var {
public static void main(String[] args) {
int Var;
Source source = new Source();
source.setSource(10);
Var = source.getSource(); // Var has value 10 in it.
}
}
Source is a class, you'll need to create an object that's a member of this class and then call the method on it. Additionally, the syntax for your method call is incorrect.
package var;
public class Source {
int source1 = 1;
public void setSource(){
source1 = 5;
}
}
Then:
package var;
public class Var {
public static void main(String[] args) {
Source source = new Source();
System.out.println(source.source1);
source.setSource();
System.out.println(source.source1);
}
}
I hope that makes sense to you when you compile it and run.
(Note that Java is case sensitive. On the above example, Source is the class and source is the object).
An alternative would be to declare methods and fields as static (static methods are called directly on the class), but I would suggest you make sure you understand the basic concepts of class and object instantiation before moving on to that.