aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes class methods vs instance method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "class methods vs instance method" Watch "class methods vs instance method" New topic
Author

class methods vs instance method

Maitham H
Greenhorn

Joined: Jan 07, 2001
Posts: 29
Can any one explain the difference between a class method and an instance method.
if you can support it with example , this would be nice.
thanks


A Software life cycle can be greater than its Developer's
Sean Casey
Ranch Hand

Joined: Dec 16, 2000
Posts: 625
I think what you mean is the difference between a static method and a instance method. The term "static" means that there is one copy and it belongs to the class while an instance member belongs to each member of the class. Here's an example:
public class Test{
public static void eat(){
System.out.println("That was good");}
public void eatDessert(){
System.out.print ln("That was very good");}
}
Now every time you create a new Test object, that object will get it's own copy of the eatDessert method that it can override. It get's its' own instance of the method. But since the eat method is declared static, no Test object will get it's own copy, but instead there will be one copy shared throughout all the class, and each member can access it. Since it's shared throughout the class, it can't be overridden. I hope this helps.
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

as sean mentioned the main difference between a static(class) method and an instance method is that instance methods can be overridden but static methods cannot. in particular, when you up cast to a superclass from a subclass the instance methods of the subclass are called but the static methods of the base class are called. In this regard static methods are similar to member variables(which also cannot be overridden). Im sure an example might help:
class Base{
void myMethod1{
System.out println("Base");
}
static void myMethod2 {
System.out.println("Base");
}
class Derived extends Base{
void myMethod1{
System.out println("Derived");
}
static void myMethod2 {
System.out.println("Derived");
}
public static void main(String[] args){
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
}
}

SCJP
Visit my download page
Monika Pasricha
Greenhorn

Joined: Jan 08, 2001
Posts: 19
Why a static method can not be overridden is not very clear to me. Plez expalin that in detail.
thanx
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Hi folks,
I have some questions about Randall's codes. I run it and it came out as Randall said. However, in case myMehtod2() in Derived actually hide myMethod2() in Base, how can we still execute the one in the base class? (I may misunderstand the meaning of hidden but surely need some clarification)
In addition, I rarely construct something in a way as
Base b = new Derived();
What exactly did it do? And why and how can it generate result as it? Is it same as Derived b=new Derived();? If not, what are differences?
Thanks a lot
Ben
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

Ben,
You are right on the money. static methods are hidden(just like member variables if we try to re-declare them in the subclass)
Base b = new Derived();
We do this a lot in java, especially upcasting to an interface. It makes it easy to deal with similar but different objects in the same way.
The best way is probably to make a Base object then you can use its methods.
Base b = new Base();
b.myMethod2();//prints Base
you can still use super though I think.
in the case of:
Derived d = new Derived();
d.myMethod1();//prints Derived
d.myMethod2();//prints Derived
welcoming replies
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Hi Randall,
Thank you for your explanation. But as a greenhorn Ben, I am still not quite clear about some points.
--Base b = new Derived();
--We do this a lot in java, especially upcasting to an interface.
If I am right, the result of this expression is same to Base b=new Base();.If so, I still cannot see why we bother to use the first expression, could you please show me one example in real world, in which we have to or had better to use this way of 'upcasting' instead of Base b=new Base();?(even not quite sure about this term. do you mean cast a subclass to a superclass?)
--It makes it easy to deal with similar but different objects in the same way.
?? Could you please show me one example?

--you can still use super though I think.
I am sorry, but I do not understand what you mean here.
Thanks a lot
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Sorry, Randall. Please forget my last post. I should have read your codes carefully! Let me think and ask you later.
Ben
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Hi Randall,
Here are my questions.
I have read a lot recently on this board that a static method cannot be overriden, but only be 'hidden'. Actually, when we use the syntax exactly as overiden on static method, as your example, we will get exactly same result as overriden (even in nature?). We JUST CANNOT call it overriden in the exam (sure, we can never try to use a staic to override an instance method, but forget that part). This is my understanding on hidden. If I am wrong, please correct me.
For codes
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
It does several things
1. Base b; (called define a Base variable b?)
2. b=new Derived(); (construct a Derived object and assign it to b, at the same time, an implicit conversion happened to convert the new construct to Base type because Base is superclass and can broad Derived's range)
My confusion lied here. If what I said above is right, b is actually a Base type, so I had expected to see output as 'base' in either case, but I did not. I know I must misunderstand some basic concepts at some points, but I do not know where. In addition, I would apprecite it if you could please give me some examples in real world application to use upcasting as this. I just cannot connect this use with the applications I wrote before.
Please help.
Ben
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

here is an excerpt from chapter 7 of "Thinking in java" which is available free from www.bruceeckel.com
Upcasting revisited
In Chapter 6 you saw how an object can be used as its own type or as an object of its base type. Taking an object reference and treating it as a reference to its base type is called upcasting, because of the way inheritance trees are drawn with the base class at the top.

You also saw a problem arise, which is embodied in the following:

//: c07:music:Music.java
// Inheritance & upcasting.
class Note {
private int value;
private Note(int val) { value = val; }
public static final Note
MIDDLE_C = new Note(0),
C_SHARP = new Note(1),
B_FLAT = new Note(2);
} // Etc.
class Instrument {
public void play(Note n) {
System.out.println("Instrument.play()");
}
}
// Wind objects are instruments
// because they have the same interface:
class Wind extends Instrument {
// Redefine interface method:
public void play(Note n) {
System.out.println("Wind.play()");
}
}
public class Music {
public static void tune(Instrument i) {
// ...
i.play(Note.MIDDLE_C);
}
public static void main(String[] args) {
Wind flute = new Wind();
tune(flute); // Upcasting
}
} ///:~
The method Music.tune( ) accepts an Instrument reference, but also anything derived from Instrument. In main( ), you can see this happening as a Wind reference is passed to tune( ), with no cast necessary. This is acceptable; the interface in Instrument must exist in Wind, because Wind is inherited from Instrument. Upcasting from Wind to Instrument may �narrow� that interface, but it cannot make it anything less than the full interface to Instrument.

Forgetting the object type
This program might seem strange to you. Why should anyone intentionally forget the type of an object? This is what happens when you upcast, and it seems like it could be much more straightforward if tune( ) simply takes a Wind reference as its argument. This brings up an essential point: If you did that, you�d need to write a new tune( ) for every type of Instrument in your system. Suppose we follow this reasoning and add Stringed and Brass instruments:

//: c07:music2:Music2.java
// Overloading instead of upcasting.
class Note {
private int value;
private Note(int val) { value = val; }
public static final Note
MIDDLE_C = new Note(0),
C_SHARP = new Note(1),
B_FLAT = new Note(2);
} // Etc.
class Instrument {
public void play(Note n) {
System.out.println("Instrument.play()");
}
}
class Wind extends Instrument {
public void play(Note n) {
System.out.println("Wind.play()");
}
}
class Stringed extends Instrument {
public void play(Note n) {
System.out.println("Stringed.play()");
}
}
class Brass extends Instrument {
public void play(Note n) {
System.out.println("Brass.play()");
}
}
public class Music2 {
public static void tune(Wind i) {
i.play(Note.MIDDLE_C);
}
public static void tune(Stringed i) {
i.play(Note.MIDDLE_C);
}
public static void tune(Brass i) {
i.play(Note.MIDDLE_C);
}
public static void main(String[] args) {
Wind flute = new Wind();
Stringed violin = new Stringed();
Brass frenchHorn = new Brass();
tune(flute); // No upcasting
tune(violin);
tune(frenchHorn);
}
} ///:~
This works, but there�s a major drawback: You must write type-specific methods for each new Instrument class you add. This means more programming in the first place, but it also means that if you want to add a new method like tune( ) or a new type of Instrument, you�ve got a lot of work to do. Add the fact that the compiler won�t give you any error messages if you forget to overload one of your methods and the whole process of working with types becomes unmanageable.

Wouldn�t it be much nicer if you could just write a single method that takes the base class as its argument, and not any of the specific derived classes? That is, wouldn�t it be nice if you could forget that there are derived classes, and write your code to talk only to the base class?

That�s exactly what polymorphism allows you to do. However, most programmers who come from a procedural programming background have a bit of trouble with the way polymorphism works.

The twist
The difficulty with Music.java can be seen by running the program. The output is Wind.play( ). This is clearly the desired output, but it doesn�t seem to make sense that it would work that way. Look at the tune( ) method:

public static void tune(Instrument i) {
// ...
i.play(Note.MIDDLE_C);
}
It receives an Instrument reference. So how can the compiler possibly know that this Instrument reference points to a Wind in this case and not a Brass or Stringed? The compiler can�t. To get a deeper understanding of the issue, it�s helpful to examine the subject of binding.

Method-call binding
Connecting a method call to a method body is called binding. When binding is performed before the program is run (by the compiler and linker, if there is one), it�s called early binding. You might not have heard the term before because it has never been an option with procedural languages. C compilers have only one kind of method call, and that�s early binding.

The confusing part of the above program revolves around early binding because the compiler cannot know the correct method to call when it has only an Instrument reference.

The solution is called late binding, which means that the binding occurs at run-time based on the type of object. Late binding is also called dynamic binding or run-time binding. When a language implements late binding, there must be some mechanism to determine the type of the object at run-time and to call the appropriate method. That is, the compiler still doesn�t know the object type, but the method-call mechanism finds out and calls the correct method body. The late-binding mechanism varies from language to language, but you can imagine that some sort of type information must be installed in the objects.

All method binding in Java uses late binding unless a method has been declared final. This means that ordinarily you don�t need to make any decisions about whether late binding will occur�it happens automatically.
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Thanks, Randall. You gave me a wonderful answer to upcasting, but I do not think it explains why b.myMethod2();//prints Base. Because if I keep my thoughts on the track of late binding, I will expect Derived as the output for b.myMethod2(I assume hidden has the same effect as overriden). But, we get base instead.
Sorry for sticking to it. I want to be crystal clear about it.
Ben
shailesh sonavadekar
Ranch Hand

Joined: Oct 12, 2000
Posts: 1874
Hi , Maitham H , Welcome to Javaranch.
Proper Names are Now Required. Maitham H, javaranch has got naming policy which everybody has to strictly follow. Please Re register yourself with proper last name & enjoy sharing wealth of knowledge.
Your Friendly Bartender
Shailesh.
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

It is because myMethod2 is a static method, so the type is determined at compile time instead of at runtime. at compile time the type of the reference(in this case Base) is used. the same is true for variables. modifying my original code:
class Base{
int i = 1;
void myMethod1{
System.out println("Base");
}
static void myMethod2 {
System.out.println("Base");
}
class Derived extends Base{
int i = 2;
void myMethod1{
System.out println("Derived");
}
static void myMethod2 {
System.out.println("Derived");
}
public static void main(String[] args){
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
System.out.println(b.i);//will print 1
}
}
hope that helps
Luka Mudischev
Greenhorn

Joined: Jan 16, 2001
Posts: 4
Hi guys. Randall, let me ask you one question, if I may. How can we make a call like b.myMethod2()(in main() method), if myMethod2 is static. In my understanding, static methods are supposed to be called like ClassName.staticMethod(), aren't they?
Originally posted by Randall Twede:
It is because myMethod2 is a static method, so the type is determined at compile time instead of at runtime. at compile time the type of the reference(in this case Base) is used. the same is true for variables. modifying my original code:
class Base{
int i = 1;
void myMethod1{
System.out println("Base");
}
static void myMethod2 {
System.out.println("Base");
}
class Derived extends Base{
int i = 2;
void myMethod1{
System.out println("Derived");
}
static void myMethod2 {
System.out.println("Derived");
}
public static void main(String[] args){
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
System.out.println(b.i);//will print 1
}
}
hope that helps

Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

you can also call them using a reference, it is just more common to call them using their classname. I would like to add one last point on this topic by writing a third method:
class Base {
int i = 1;
void myMethod1 {
System.out println("Base");
}
static void myMethod2 {
System.out.println("Base");
}
void myMethod3 {
System.out.println(i);
}
}
class Derived extends Base {
int i = 2;
void myMethod1 {
System.out println("Derived");
}
static void myMethod2 {
System.out.println("Derived");
}
public static void main(String[] args){
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
System.out.println(b.i);//will print 1
b.myMethod3();//will print 2
}
}
Someone please correct me if anything I have said is wrong.
[This message has been edited by Randall Twede (edited January 19, 2001).]
[This message has been edited by Randall Twede (edited January 19, 2001).]
Luka Mudischev
Greenhorn

Joined: Jan 16, 2001
Posts: 4
Randall, thank you very much for your reply.
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Hi Randall,
Thanks for your help. This answer is quite clear. In fact, I am very suprised that b.i comes out as 1. I would have thought that only variable declared as static can avoid late-binding. I have tried to find the context related to your explanation in ThinkingInJava, but get lost in a jungle. If possible, could you please let me know where I can find this specification, either in TIJ or other resources? Thanks a lot.
For Luka's question, I believe that you do not have to construct an instance to call static method, instead, you can directly use class name to call it. However, that does not mean you cannot build an object of the class and use it to call the static method, as the example from Randall.
Thanks
Ben
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Hi Randall,
myMethod3() is a great example. I got your point, but I think you forgot to override myMethod3 in Derived class. I am attaching the runnable codes if anyone wants to test it.
I still hope you could please implement me the refernece about my last question, if possible.
Ben
class Base{
int i = 1;
void myMethod1(){
System.out.println("Base");
}
static void myMethod2() {
System.out.println("Base");
}
void myMethod3() {
System.out.println(i);
}
}
class Derived extends Base{
int i = 2;
void myMethod1(){
System.out.println("Derived");
}
static void myMethod2() {
System.out.println("Derived");
}
void myMethod3() {
System.out.println(i);
}
public static void main(String[] args){
Base b = new Derived();
b.myMethod1();//prints Derived
b.myMethod2();//prints Base
System.out.println(b.i);//will print 1
b.myMethod3();//will print 2
}
}
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

I found this in the JLS(java language specification)
15.11.1 Field Access Using a Primary

Note, specifically, that only the type of the Primary expression, not the class of the actual object referred to at run time, is used in determining which field to use.
Thus, the example:

class S { int x = 0; }
class T extends S { int x = 1; }
class Test {
public static void main(String[] args) {
T t = new T();
System.out.println("t.x=" + t.x + when("t", t));
S s = new S();
System.out.println("s.x=" + s.x + when("s", s));
s = t;
System.out.println("s.x=" + s.x + when("s", s));
}
static String when(String name, Object t) {
return " when " + name + " holds a "
+ t.getClass() + " at run time.";
}
}
produces the output:
t.x=1 when t holds a class T at run time.
s.x=0 when s holds a class S at run time.
s.x=0 when s holds a class T at run time.
The last line shows that, indeed, the field that is accessed does not depend on the run-time class of the referenced object; even if s holds a reference to an object of class T, the expression s.x refers to the x field of class S, because the type of the expression s is S. Objects of class T contain two fields named x, one for class T and one for its superclass S.
This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available in, but only when instance methods are used. Consider the same example using instance methods to access the fields:

class S { int x = 0; int z() { return x; } }
class T extends S { int x = 1; int z() { return x; } }
class Test {
public static void main(String[] args) {
T t = new T();
System.out.println("t.z()=" + t.z() + when("t", t));
S s = new S();
System.out.println("s.z()=" + s.z() + when("s", s));
s = t;
System.out.println("s.z()=" + s.z() + when("s", s));
}
static String when(String name, Object t) {
return " when " + name + " holds a "
+ t.getClass() + " at run time.";
}
}
Now the output is:
t.z()=1 when t holds a class T at run time.
s.z()=0 when s holds a class S at run time.
s.z()=1 when s holds a class T at run time.
The last line shows that, indeed, the method that is accessed does depend on the run-time class of referenced object; when s holds a reference to an object of class T, the expression s.z() refers to the z method of class T, despite the fact that the type of the expression s is S. Method z of class T overrides method z of class S.
Chris Ben
Ranch Hand

Joined: Jan 15, 2001
Posts: 135
Thanks a lot, Randall.
Have a good night
Ben
anurag priya
Ranch Hand

Joined: Dec 19, 2000
Posts: 72
dear rand !
" static methods cannot be overridden"
i think its not correct !
" static methods cannot be overridden to make them non static ! what i mean to say is that any method which is a class method can be overridden in the sub class iff it is statically overridden :
e.g.:
class A
{
static public void meth(){}
}
class B extends A
{
static public void meth(){ System.out.println(" working "); }
}
class staticdemo
{
static private void main (String []p)
{
B.meth();
}
}

is it the same method overridden in class B" static public void meth() " that of class A or something different.
please comment ! anurag


Anurag priya
SCJP 2(83%); Brain Bench Certified for: Masters level EJB2.0(97%) - Masters level J2EE (83%) - BEA-WebLogic Application Server8.1 (86% )
Randall Twede
Ranch Hand

Joined: Oct 21, 2000
Posts: 4347
    
    2

Many people have trouble with this. I did too. I will quote the JLS again:
8.4.6.1 Overriding (by Instance Methods)
An instance method m1 declared in a class C overrides another method with the same signature, m2, declared in class A if both
C is a subclass of A.
Either
m2 is non-private and accessible from C, or
m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, such that m3 overrides m2.
Moreover, if m1 is not abstract, then m1 is said to implement any and all declarations of abstract methods that it overrides.
A compile-time error occurs if an instance method overrides a static method.
In this respect, overriding of methods differs from hiding of fields (�8.3), for it is permissible for an instance variable to hide a static variable.
An overridden method can be accessed by using a method invocation expression (�15.12) that contains the keyword super. Note that a qualified name or a cast to a superclass type is not effective in attempting to access an overridden method; in this respect, overriding of methods differs from hiding of fields. See �15.12.4.9 for discussion and examples of this point.
The presence or absence of the strictfp modifier has absolutely no effect on the rules for overriding methods and implementing abstract methods. For example, it is permitted for a method that is not FP-strict to override an FP-strict method and it is permitted for an FP-strict method to override a method that is not FP-strict.

8.4.6.2 Hiding (by Class Methods)
If a class declares a static method, then the declaration of that method is said to hide any and all methods with the same signature in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class. A compile-time error occurs if a static method hides an instance method.
In this respect, hiding of methods differs from hiding of fields (�8.3), for it is permissible for a static variable to hide an instance variable. Hiding is also distinct from shadowing (�6.3.1) and obscuring (�6.3.2).
A hidden method can be accessed by using a qualified name or by using a method invocation expression (�15.12) that contains the keyword super or a cast to a superclass type. In this respect, hiding of methods is similar to hiding of fields.
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi Anurag,
There is a Sun Tech Tip that explains the difference between Overriding, Shadowing and Hiding.
It includes the following example code and explanation:

Explanation:

Hope that helps.
------------------

Jane Griscti
Sun Certified Java 2 Programmer
"When ideas fail, words come in very handy" -- Goethe


Jane Griscti
SCJP, Co-author Mike Meyers' Java 2 Certification Passport
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: class methods vs instance method