140 likes | 272 Views
Ruby Modules, Subclasses, etc. and other languages… . Extending Class Behavior. Modules covered next lecture. May create subclasses (inheritance) May include/inherit methods from modules (mix-ins) Clients of class may also extend: Classes are open; any program can add a method
E N D
Ruby Modules, Subclasses, etc. and other languages…
Extending Class Behavior Modules covered next lecture • May create subclasses (inheritance) • May include/inherit methods from modules (mix-ins) • Clients of class may also extend: • Classes are open; any program can add a method • Can add a singleton method to an individual object
Inheritance • Object is the superclass if none specified • BasicObject is parent of Object • Few methods, useful for wrapper classes • Every class has a single superclass • May have multiple subclasses – a hierarchy • Syntax: class Student < Person end
Inheritance and instance variables What are some pros and cons? What about “shadowing”? Every Ruby object has a set of instance variables These are not defined by the class! Instance variables are created when a value is assigned If all variables are defined in initialize, inheritance appears to work as expected But instance variables may be created by other methods! (Since methods are inherited, may still appear to inherit variables… but may not!) Bottom line: Instance variables have nothing to do with inheritance.
Simple Example class Person def initialize(name) @name = name puts "initializing" end end class Student < Person def to_s puts "Name: #{@name}" end end s = Student.new("Cyndi") puts s • Technically @name is not inherited • BUT, initialize is called, so @name is created for the Student object • It appears that the variable is inherited • An instance variable created in a parent method that is not called by the child will not exist
Method Visibility Compare to Java/C++ • public. • methods are public by default. • initialize is implicitly private (called by new) • private. • only visible to other methods of the class (or subclass) • implicitly invoked on self (but can’t write self.fn) • protected • like private, but can be invoked on any instance of the class (e.g., if pass in parameter… allows objects of same type to share state) • used infrequently • Applies only to methods! • Variables are automatically encapsulated (private) • Constants are public
Method visibility class X # public methods def fn #stuff end protected :fn def helper #stuff end private :helper end • can override visibility, e.g., private_class_method :new • private and protected guard against inadvertent use – BUT, with metaprogramming it’s possible to invoke these methods. Compare to Java/C++
Inheriting and Overriding Compare to Java… what is initialize? Is it inherited? Can override methods Methods are bound dynamically (when executed) not statically (when parsed) Methods like to_s and initialize are automatically inherited Caution: if you don’t know all methods of a class you’re subclassing, you may override a private method accidentally! Caution: class methods can be overridden, but it’s best to invoke class method with name of class that defines it.
Override parent method class Person def initialize(name) @name = name end def greeting puts "Hi, my name is #{@name}" end end class Student < Person def greeting puts "Hi, I'm a student and my name is #{@name}" end end me = Person.new("Cyndi") me.greeting you = Student.new("Suzie") you.greeting
Abstract Class abstract methods concrete class: defines all abstract methods of ancesters class AbstractGreeter def greet puts "#{greeting} #{who}" end def say_hi puts "hi" end end class WorldGreeter < AbstractGreeter def greeting; "Hello"; end def who; "World"; end end WorldGreeter.new.greet # AbstractGreeter.new.greet (error!) AbstractGreeter.new.say_hi
Chaining methods class Person def initialize(name) @name = name end def long_greeting puts "Hi, my name is #{@name}." end end class Student < Person def initialize(name, major) super(name) # could do just super @major = major end def long_greeting super puts "I am studying #{@major}." end end me = Person.new("Cyndi") me.long_greeting you = Student.new("Suzie", "CS") you.long_greeting super is a little different from Java – how?
Inheritance and class variables Class variables can be used by class and all its subclasses This is not inheritance – why? Class constants are inherited. Can be redefined in the subclass (Ruby issues warning).
Class variable example class Person def initialize(name) @name = name @@what = 12 end def show puts "Person: #{@@something}" end end class Student < Person def make_something @@something = 15 end def show puts "Student: #{@@something} and #{@@what}" end end me = Person.new("Cyndi") you = Student.new("Suzie") # creates class variable something you.make_something you.show who = Student.new("Joe") # both Students can access something who.show # parent cannot access something # me.show # error