Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 8, 2021 05:49 pm GMT

Public vs. Private vs. Protected

For anyone learning Object Oriented Programming or Ruby or both, you know that there is a lot to learn. Im still learning new things everyday. One of the topics that bothered me, and still bothers me, is the difference between public, private and protected instance methods.

As an attempt to better understand them, Ive done some research on the topic and am writing down what Ive learned. Hopefully this article will not only clear up the matter in my own head but help anyone else who is confused as well.

A basic understanding of Object Oriented Programming will be needed to understand this article. If you are unfamiliar with OOP, I suggest reading up on it first.

First Things First

What are public, private, and protected instance methods? Why do we use them? When do we use them?

To make it simple: public, private and protected methods are just that. Methods. You use them to perform certain functions on your code. The difference between the three comes from who and/or what has access to them.

Why do we use them? To provide a easy and simple interface for our classes. They allow us to write clean code and provide a enjoyable experience for the consumers of that code while protecting any sensitive data at the same time.

As for when do we use each one, that will require us to go more in-depth.

Public

Public methods are the generally considered the easiest to understand out of the three.

What are they?

Public methods are methods that are accessible both inside and outside the scope of your class. Any instance of that class will have access to public methods and can invoke them.

How do you use them?

You use them as you would any other method in ruby. Using dot notation, you can invoke a public method on a caller.

Lets see it in action:

class Person  def initialize(name, age)    @name = name    @age = age  end  public  def name    @name  end  def age    @age  endendjoe = Person.new('Joe', 30)joe.name                    # => 'Joe'joe.age                     # => 30
Enter fullscreen mode Exit fullscreen mode

You can see above that joe is an instance of class Person. Since name and age are public instance methods, the joe object can access them even outside the scope of class Person.

As a side-note: you dont need to preface public instance methods with public like I did in the code snippet above. All instance methods are public by default. I just did that to make it more clear.

When do you use them?

You certainly want to use public methods when displaying information for everyone to see.

A public method in human form.A public method in human form.

You should also keep a method public if it is a part of that classs interface. Meaning that other classes interact with that class via that method. Since that last sentence made no sense, heres an example:

class Dog  attr_reader :name  def initialize(name)    @name = name  end  def speak    'Arf!'  endendclass Owner  attr_reader :name, :pet  def initialize(name, pet_name)    @name = name    @pet = Dog.new(pet_name)  end  def call_pet    puts "#{name}: Hey #{pet.name}! Come here boy!"    puts "#{pet.name}: #{pet.speak}"  endendtom = Owner.new('Tom', 'Rufus')tom.call_pet  # => "Tom: Hey Rufus! Come here boy!"# => "Rufus: Arf!"
Enter fullscreen mode Exit fullscreen mode

The above example is a bit long, but you can see that the speak method in the Dog class is part of its interface. The Owner class uses that method in its call_pet method to allow the pet to speak. Also, we could use *speak *method by itself if we want the dog object to speak on its own. Therefore we should keep it a public method

Its also important to keep your method public when you want the program/client to be able to change the state of your object. For instance, say you have a car object and you want to spray paint it a different color:

class Car  def initialize(color)    @color = color  end  def spray_paint(new_color)    @color = new_color  end  def color    @color  endendmy_car = Car.new('pink')my_car.color               # => 'pink'my_car.spray_paint('black')my_car.color               # => 'black'
Enter fullscreen mode Exit fullscreen mode

Private

Private methods are probably the next easiest to understand as protected are a bit more nuanced.

What are they?

Private methods are not accessible outside the scope of the class whatsoever. If you try to invoke a private method with a class object, an error will occur.

class TopSecret  private  def data    "Top secret information"  endend secret_file = TopSecret.newsecret_file.data           # => NoMethodError: private method `data' called for #<TopSecret:0x007f8051041ab8>
Enter fullscreen mode Exit fullscreen mode

How do you use them?

You may have also noticed that in order to make a method private, you have to preface it with the keyword private. *Any methods that you create underneath *private will be considered private methods and off limits.

(private is actually a ruby method itself, but it may be easier to think of it as a keyword/section divider)

Furthermore, private methods do not use dot notation and can only be called implicitly. This means that you will never reference self, or any other class instance, on a private method.

If you want to use a private method within the proper scope, just call it by its method name. Simple as that.

class Mathy  def output_result(num1, num2)    puts crazy_algorithm(num1, num2)  end  private  def crazy_algorithm(num1, num2)    value = num1 * num2    value *= (num1 + num2)    value /= num1    value -= num2 / num1    value**2  endendequation = Mathy.newequation.output_result(3, 5)    # => 1521
Enter fullscreen mode Exit fullscreen mode

When do you use them?

Private methods are very useful when it comes to managing the interface of both your class and your program. They should be used when dealing with:

  • Sensitive information, such as passwords, personal information, etc.

  • Methods that serve as the inner workings of your class and dont output or display information.

  • Methods that dont add to the interface and do not collaborate with other classes.

If youre a developer building a video game app, you wouldnt want the player to have access to the game settings, computer AI, or any other of the inner functions.

What happens when you dont use private methodsWhat happens when you dont use private methods

What about when you want certain people to access the information, but not everyone? Thats when you can use a public method to act as a go-between. This allows you to create a filter that only lets some people through. A password is a good example.

class TopSecret  def access_data        puts "Please enter password:"    password_attempt = gets.chomp    if password_attempt == '12345'      puts data    else      puts 'Nice try, bozo.'    end  end  private  def data    "Top secret information"  endendsecret_file = TopSecret.newsecret_file.access_data
Enter fullscreen mode Exit fullscreen mode

In the above example, the data method is private so neither the client nor the program has access to it. But a secret is only fun if some people have access to it and they can shove it everyone elses face, so I created a accessor method called access_data.

The access_data method requires a password from the user before it gives up its secrets. A wrong password attempt leaves them being called a bozo.

Protected

We now come to the protected instance methods, the odd one of the group.

What are they?

Protected methods are a balance between public and private methods. They are similar to private methods in that they cannot be accessed in the public scope. Neither the client nor the program can invoke them.

class Person  def initialize    @age = rand(50)  end  protected  def age    @age  endendme = Person.newme.age          # => NoMethodError: protected method `age' called
Enter fullscreen mode Exit fullscreen mode

However, objects of the same class can access each others protected methods.

class Person  def initialize    @age = rand(50)  end  def >(other_person)    age > other_person.age  endprotecteddef age    @age  endendme = Person.newyou = Person.newme > you         # => true
Enter fullscreen mode Exit fullscreen mode

The ages are generated at random so the result of the above code wont always be true. However, it will never produce an error, which is the most important take away.

Since you *and *me are objects of the same class Person they can access each others protected methods without issue.

How do you use them?

If you want to make a method protected, you must declare the protected *method first, similar to private methods. However, with protected methods, you *can *use dot notation and call **self* or another receiver.

class Person  def younger_than?(other_person)    self.age < other_person.age  end  protected  def age    @age  endend
Enter fullscreen mode Exit fullscreen mode

When do you use them?

The best time to create a method under the protected heading is when you want to compare and/or transfer data between objects of the same class, but you dont want that information to be made public.

Say Im building a banking game and I want to keep the account balance information private. However, I want to include features that let me know whether I have more money than a friend and to steal from them.

class BankAccount  def initialize    @balance = rand(100)  end  def richer_than(other_account)    if balance > other_account.balance      puts "You're rich!"    else      puts "Better luck next time."    end  end  def steal_from(other_account, amount)    if amount > other_account.balance      puts "Hold it there, they aren't that rich."      return    else      @balance = @balance + amount      other_account.balance = other_account.balance - amount      return    end  end  protected  def balance    @balance  end  def balance=(num)    @balance = num  endendmy_account = BankAccount.newfriend_account = BankAccount.newmy_account.richer_than(friend_account)# => "Better luck next time."my_account.steal_from(friend_account, 25)my_account.richer_than(friend_account)# => "You're rich!"my_account.balance    # => NoMethodError
Enter fullscreen mode Exit fullscreen mode

Lets break down the above code.

I made the balance getter method protected, so it is not available to the public scope and theres no way of actually knowing how much money is in the account.

The richer_than method takes another BankAccount object as an argument and lets you know if your own account has more money than theirs.

The steal_from method takes two arguments, a BankAccount object and how much money to take from it. However, since you dont know how much money the other bank account has, you have to make a guess of how much to take. That is why it lets you know if youve taken too much.

Finally, I invoke the getter balance method at the end just to reiterate that calling a protected method will result in an error.

Summary

Public instance methods:

  • Accessible from global scope.
  • Part of the class interface.
  • All instance methods are public by default.
  • Use if displaying information or interacting with other classes and/or the client.

Private instance methods:

  • Accessible only from within class scope.
  • Part of the class inner-workings.
  • Must preface with private method.
  • Use when hiding sensitive information or crucial class methods.

Protected instance methods:

  • Accessible from within class scope and by objects of the same class.
  • Must preface with protected method.
  • Use when wanting to compare/interact with other class objects, but dont want the program or client to have access to them.

There you have it. An in-depth look at public, private and protected methods. I hope this has been as helpful to you as it has been to me.

Now go and make some awesome object oriented programs!


Original Link: https://dev.to/sunnyb/public-vs-private-vs-protected-9hk

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To