dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: question on inheritance

  1. #1
    Join Date
    Aug 2003
    Posts
    90

    Question question on inheritance

    hi,

    here is some very simple questions.....

    Code:
    class Book2 {
      protected int pages;
    
      public Book2(int pages) 
     
      {
        this.pages = pages;
      }
    
      public void pageMessage() {
        System.out.println("Number of pages: " + 
                           pages);
      }
    }
    in this code i simply want to know what is the use of "this" keyword.

    i could simply do it by...

    pages = pages; // i removed "this"

    i am not saying that code is wrong.....but where should i use "this"... without "this" it can be done ..is not it?

    is it just a fancy way of programming?



    question
    -------------
    Code:
    class Student { ... }
    class Undergraduate extends Student { ... }
    class Graduate extends Student { ... }
    
    Student student1, student2;
    student1 = new Undergraduate(); // ok
    student2 = new Graduate();      // ok

    how this is ok?

    student1 = new Undergraduate();

    i would have satisfied with

    Student student1= new Student ();

    or

    Undergraduate x = new Undergraduate();

    but you notice above declaration has mixed classes.....how is it possible??


    its calling the subclasses " constructor" and using" new" keyword to get an object of the superclass.....is not it peculiar??

  2. #2
    Join Date
    Apr 2001
    Location
    South Africa, Jo'burg
    Posts
    680
    Hi,

    The this keyword tells the vm that you are interested in working with the pages variable belonging to the class and not the parameter pages. without 'this' you would be assigning the value of the parameter to itself and possibly lose the data once the constructor is finished. By using this you will assign the value to the correct variable.

    The second question you have asked is an example of polymorphism in use. That code is legal and will work since Graduate and Undergraduate are both subclasses of Student. In short both Undergraduates and Graduates ARE Students, they inherit all methods and variables from Student. So there is no harm in referencing objects like that.

    Hope this helps
    Byron

  3. #3
    Join Date
    Aug 2003
    Posts
    90
    That code is legal and will work since Graduate and Undergraduate are both subclasses of Student. In short both Undergraduates and Graduates ARE Students, they inherit all methods and variables from Student. So there is no harm in referencing objects like that.

    hi, i am not clear .


    can you tell me

    what is the differnce between

    Student student1 = new Student ();

    AND

    Student student1 = new Undergraduate();

    here both of them are creating studentn1 instance .....is there any difference between two?



    about the answer of your first question you are talking about pages....what is that ? i am not geting the point. can you explain in a simpler way??

    i am expecting very simple answer...as i am new to java.

    my question was i could easily bypass "this" keyword...its not at all mandatory. is it right??

    thanks

  4. #4
    Join Date
    Dec 2003
    Location
    UK
    Posts
    113
    To answer your first question:
    Code:
    class Book2 {
      protected int pages;
    
      public Book2(int pages) 
     
      {
        this.pages = pages;
      }
    The
    Code:
     protected int pages;
    defines an attribute of your Book2 class. It is thus a property of the class - ie. a Book has x number of pages.

    Code:
    public Book2(int pages)
    is the constructor of your Book2 class. This is passed a "temporary" field that is accessed inside the constructor. Check the chapter on scope of variables.

    Because you used the same name for the variable and the attribute the compiler will get "confused" and don't know which one you are talking about. That is because the attribute can be seen/accessed inside your constructor.

    By specifying "this.pages" you inform the compiler that you are talking about the attribute and not the variable. You are actually telling it to set the attribute to the same value as the variable passed in. It also makes it clear to anyone else trying to read your code. You could also name the two fields differently and then not confuse yourself.

    When you start doing "get" and "set" methods later on you will see this technique used a lot. It is used to implement encapsulation. Thus making your properties/attributes private and only permitting access to them via public methods. This is one of the strong/selling points of Java (and OO) so learn it well.

    Hope this helps

  5. #5
    Join Date
    Dec 2003
    Location
    UK
    Posts
    113
    Question 2:

    You really have to read the chapter on polymorphism, because it will take too long to explain in detail. You will most probably also have to understand abstract classes to see this easily implemented together with the principle of inheritance.

    Undergraduate and Graduate are both sub-classes of Student. Thus they ARE students. You can cast a subclass into a super class and then perform actions on the sub-class by referencing the super-class (polymorphism).

    See I told you it will not make sense if I try to explain it to you....

  6. #6
    Join Date
    Nov 2002
    Location
    Brazil
    Posts
    181
    this is a reference to the current instance.

    Code:
    public Book2(int pages) 
    {
        this.pages = pages;
    }
    In this case, the keyword this is necessary, because both the parameter variable and the object attribute share the same name, therefore there's a conflict. By ommitting this, you never do anything involving the object attribute, because 'pages' refers to the parameter. this wouldn't have been necessary if the names were different.


    Student student1 = new Student (); // instantiates a Student object

    Student student1 = new Undergraduate(); // instantiates an Undergraduate object

    Since both have been declared as Student, both are bound by the same set of accessible attributes and methods at this time. However, you may perform a class cast on the second object, which is an Undergraduate one, if you wish to make use of specific variables and methods that aren't defined in the Student class signature, but are a part of the Undergraduate class one.

    Essentially, you can instantiate any Object that has a public constructor with no arguments by declaring it as Object, and then calling the valid empty constructor of a desired class. For example:
    Code:
    Object integer = new Integer();
    However, it's not very likely for this to be a good idea in an actual program. :P

    Likewise, any method that expects an "Object object" can receive any object, because all classes in Java are subclasses of the Object class. It may seem a bit confusing since you're new to Java (OO too?), but give yourself time to gradually assimilate all this and you'll realize it's really quite logical.

    Check this out: http://www.javaranch.com/campfire/StoryPoly.jsp .
    Last edited by Magus; February 16th, 2004 at 09:39 AM.

  7. #7
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    *remembers a discussion about the this keyword, and the problems it engenders..*

    to understand the THIS keyword, examine the 2 code fragments (they work identically):

    Code:
    public class Student{
    
      private int age;
    
      public Student(int age){
        this.age = age;
      }
    }
    
    public class Student{
    
      private int age;
    
      public Student(int theAge){
        age = theAge;
      }
    }
    I was taught the second form at university, and recently found myself debating on this forum, that it is much clearer what the code is actually doing.. what do you think?
    The basis of my point was that the concept of "this" is quite hard to understand, especially when youre being taught what a "scope" is, what curly brackets are for, when you should use them, why variables disappear sometimes, why you cant declare variables twice, etc.. It's better to leave the use of "this" out of code until youre more advanced with java, when you can be told, that use of "this" refers to the instantiated object (or class, if it is static) itself.. often the java compiler inserts "this" for you, without your knowing:

    Code:
    public class ThisExample{
    
      public void aMethod(){
        //blah
      }
    
      public void withoutThis(){
        aMethod();
      }
    
      public void withThis(){
        this.aMethod();
      }
    }
    both methods, withThis() and withoutThis() will work the same.. the "this" directive simply tells java to call the method on this class..
    There is another keyword, that works in tandem with "this", called "super".. it refers to the parent class. All classes (apart from Object) have a parent class.. and if you explicitly need to address soemthing about the parent class, you call super.(whatever). you will most often encounter super in constructors, where it takes on a special use, as a word on its own:

    Code:
    public class Child extends Parent{
      public Child(){ //the constructor
        super();  //call the parent's constructor
        //do additional things that the parent constructor does not?
      }
    }

    ----------

    To explain polymorphism, i wont use your Student->Undergrad/Postgrad example, if thats okay.. i'll pick on another one that showed recently..

    Imagine that you have a class called Shape. All Shapes have a numberOfSides, a width and a height (at least)

    So we make a parent class:
    Code:
    public class Shape{
      protected int numberOfSides, width, height;
    }
    suppose our shapes also know how to draw themselves, when we tell them what Canvas (its a GUI component) we want them to draw on:

    Code:
    public abstract class Shape{
      protected int numberOfSides, width, height;
    }
    
    public void drawYourself(Canvas drawOn){
    }
    notice, ive made this class abstract now; you cant actually use the keyword "new" with this class anymore.. its not possible to make "just a shape" bu writing "Shape s = new Shape();"

    youll see why:
    Code:
    public class Square extends Shape{
      public Square(){
        super(); //call shape's constructor
        super.numberOfSides = 4;
        super.width = 10;
        super.height = 20;
      }
    }
    technically, i dont need to put all those "super.xxxx" in there, but it reminds me where the variable is.. otherwise i might be sittign there thinking "uh.. i cant even see where numberOfSides variable is!" - its in the parent class= the super class

    and now we over-ride the rather useless method for drawing itself, in Shape, with one that is meaningful:
    Code:
    public class Square extends Shape{
      public Square(){
        super(); //call shape's constructor
        super.numberOfSides = 4;
        super.width = 10;
        super.height = 20;
      }
    
      public void drawYourself(Canvas c){
        //draw the shape at grid coords 10,10
        c.getGraphics().drawRectangle(width, height, 10, 10);
      }
    }
    big deal, you say... whats the use of inheritance?
    well, lets make a circle:

    Code:
    public class Circle extends Shape{
      public Circle(){
        super(); //call shape's constructor
        super.numberOfSides = 1;
        super.width = 50;
        super.height = 100;
      }
    
      public void drawYourself(Canvas c){
        //draw the shape at grid coords 10,10
        c.getGraphics().drawEllipse(width, height, 10, 10);
      }
    }
    again, big deal you say.. why bother extending when you could jsut write a different class anyway? well the thing is, we can now treat them both as just Shapes! so your drawing app only knows what a shape is, and it knows it can make the shape draw itself.. you dont need to reprogram the drawing app at all now.. whenever you want another shape, say, a triangle, write the class for it, and so long as it extends Shape, your drawing program can use it:

    Code:
    public class DrawingProgram{
      public Shape[] theShapes = new Shape[100];
    
    ...
    remember! when we make an array, we arent actually making a Shape object.. we are making an array object capable of holding shapes.. we CANT say this:

    theShapes[0] = new SHape();

    because new Shape() is not allowed, Shape is abstract - it represents a concept, not an object


    we CAN say this:

    theShapes[0] = new Square();
    theShapes[1] = new Circle();

    ...

    now, your drawing program can have circles AND squares, and it doesnt care which is what.. it jsut says "draw yourself"
    if theShapes[0] (which is of type Shape) is an instance of a Square, then calling theShapes[0].drawYourself() will cause a square to be drawn.. if theShapes[0] were an instance of Circle then a circle would be drawn
    To extend the functionality, you just make a Triangle extends Shape, Parallelogram extends Shape, Hexagon extends Shape.. and so on, and your drawing program can load them, treat them as Shapes (not individual circle/square/triangle/hexagon etc) and make them draw themselves

    do you see the power of inheritance? you can baically say "right, all these objects belong to a group called X, and collectively, they all can do the same thing Y. Now, Y changes depending on what the object is, but they all do Y, so if we make a parent class that defines Y, we can change the implmentation for the individuals of the group. Then, we can get some sort of response out of the whole group, by calling Y.. and it is guaranteed that all members of the group will at least know what to do when Y is called."

    for your Student.. maybe all students will goToALecture(), but a Undergrad will just go, whereas a Postgrad might be teaching the lecture, so he will have to getSupportingMaterials() before he can goToLectureRoom(String whichRoom).
    If the Undergrad has to take his homework.. he might getMyHomework(String forWhichLecture) before he can goToLectureRoom(String whichRoom)

    - in both cases a Postgrad and an Undergrad goToALecture()
    but the behaviour that they exhibit in doing so, is different.. inheritance allows that and treat them generically, without having to know if the object is a postgrad, and that is an undergrad etc.. we let the object itself decide what to do, not the class that is giving it orders..
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  8. #8
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    Originally posted by TheMummy
    here both of them are creating studentn1 instance .....is there any difference between two?
    It is more correct, and helpful to your understanding, if you say:

    Both of them are creating an object. I can refer to that object using the name studentn1. BUT, the crucial difference is, that while an Undergraduate IS-A Student, it does not necessarily mean that a Student IS-A Undergraduate.

    THink about the naming here. Imagine your name is John. If i see you in the street, i can say "Hey Man!", or i can say "Hey John"
    I can also say to the next person behind you.. "Hey Man!", but if his name is Phil, i cant say "Hey John"
    John IS-A Man
    Phil IS-A Man
    but John IS-NOT-A Phil (and vice versa)

    so i can convert between using John/Man and Phil/Man to refer to the person.
    If i were to say "John, pick up your litter" you could comply. If i said "man, pick up your litter", again you would respond

    Only one of these statements will work on both Phil and John though.. if i say "John, pick up your litter" to Phil, he wont know what im talking about.

    Translating this into java:
    Whether your studentn1 IS-A Student, a Postgrad or a Undergrad, they have some things that make them both the same.. (like john and phil responding to man) and some things that make them different

    make no mistake though, you can do this:
    Student s1 = new Student();
    Student s2 = new Undergraduate();
    Student s3 = new Postgraduate();

    you CANT do this:
    Postgraduate p1 = new Student();
    Undergraduate u1 = new Student();
    Undergraduate u2 = new Postgraduate();

    why, requires some more explaining:

    making a Undergraduate, who IS-A student, DOESNT mean you can convert him to a Postgrad (who also IS-A Student) any more than i can convert you into phil.. if you need to use a Undergrad, make sure you make an Undergrad, if you need to use a Postgrad, make sure you make a Postgrad.. though because they both descend from students, you can stuff them into containers declared to hold things of type Student (i.e. Student studentn1 is a container for Students, but Undergrad and Postgrad will fit too.. and behave differently, maybe )

    Now, this bit used to confuse me:
    A postgrad IS-A student, so why cant i declare a Postgrad and set him = to be a new Student()? You cant because being a Student is just a generic type - it might contain anything, and a Postgrad is a very specific type.
    Talking about Mercedes, BMW and Porsches.. they are all Cars.. Car is the generic, Mercedes, BMW, Porsche is the specific.
    You cant walk into a car dealership and say "I want a new car" - they will say "can you be more specific? what car do you want?"
    So do you see why you cant say Mercedes m = new Car(); ? the Car type is too generic;
    Because you can say Car c = new Mercedes(), or new BMW(), or new Porsche(), the the Car() container could have inside it a Porsche, BMW or Mercedes.. java cant guess how you would convert the BMW into a Mercedes:

    Car c = new Mercedes();
    BMW b = new Car(); //doesnt work, why not? see the next line:
    BMW b = c; //c IS-A car, specifically, IS-A Merc, java knows you cant convert a merc to a beemer

    so thats why you can assign a specific object to a generic container, but not the other way round; that generic container might contain a specific type, and java cant assign 1 specific type to another - you get errors

    my question was i could easily bypass "this" keyword...its not at all mandatory. is it right??
    "this" is not mandatory, and is confusing.. add the word "the" to your method parameters to get round the issue, neither is any more "correct" than the other, but one of them's a darn sight easier to understand:
    Code:
    public class Whatever{
    
      int a,b,c,d;
    
      public Whatever(int theA, int theB, int theC, int theD){
        a = theA;
        b = theB;
        c = theC;
        d = theD;
      }
    }
    Last edited by cjard; February 16th, 2004 at 01:59 PM.
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  9. #9
    Join Date
    Aug 2003
    Posts
    90
    hi,
    cjard

    thanks for the nice ,interactive,clear,elaborated explanation........it really helped me to understand more.....that question haunted me long time.... i appreciate your presentation skill to make others to understand in a simple way.....I find this article very effective .....its ok now.

    thanks

  10. #10
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    maybe i should FAQ it thanks for the comments!

    matt
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)