Public, Protected and Private refer to the accessibility of those methods.
By default, all methods are Public. If you do not specify the accessibility of a method, it will be Public. 
Protected and Private methods are not publicly accessible and so when  you have an instance of an Object you will not be able to call those  methods.
Protected and Private methods also have differences around how you can use them within the context of an Object. 
Private Methods
 
Both Private and Protected methods are not accessible from outside of the object as they are used internally to the object. 
Another important aspect of good object-oriented design is that the  consumer of an object should not have to know how that object is  implemented.
Private methods and Protected methods, whilst both being inaccessible  outside of the scope of the object, have a subtle difference.
I think it’s easier to understand Private methods, and so we’ll start here.
To define a private method you use the private keyword. private is not actually a keyword, it’s a method, but for all intents and purposes, it’s easier to just think of it as a keyword.
For example, we might have the following method in our Product class:
class Product
attr_accessor :name, :quantity
def initialize(name)
      @name = name
      @quantity = 1
end
def increment
      @quantity += 1
end
private
      def stock_count
         100
      end
end
To signify that the 
stock_count method is private we can place it under the 
private heading.
There is actually a couple of different ways to define private methods, but I think the method above is the most common.
Now when we have an instance of the 
Product object, we can’t call the 
stock_count method because it is private:
milk = Product.new("Milk")
=> #
milk.stock_count
NoMethodError: private method 'stock_count' called for #
 
In order to call the stock_count method, you need to be within the scope of the object:
class Product
attr_accessor :name, :quantity
def initialize(name)
      @name = name
      @quantity = 1
puts "There are #{stock_count} in stock"
end
def increment
      @quantity += 1
end
private
      def stock_count
         100
      end
end
 
Now when we instantiate a new instance of the object, we will see the stock count:
milk = Product.new("Milk")
  There are 100 in stock
=> #
 
So the only way to call a Private method is to do so within the context of the object instance.
However, an interesting thing to note about Private Ruby methods is  the fact that a Private method cannot be called with an explicit  receiver, even if that receiver is itself.
When I say “receiver”, I mean the object that the method is being called from.
So for example:
class Product
    attr_accessor :name, :quantity
def initialize(name)
      @name = name
      @quantity = 1
puts "There are #{self.stock_count} in stock"
end
private
      def stock_count
         100
      end
end
In this example I’ve modified the 
initialize method to use 
self.stock_count. In this case, 
self refers to the current object.
However, when you attempt to create a new instance of 
Product you will get an error:
milk = Product.new("milk")
NoMethodError: private method `stock_count’ called for #
So you can only call Private methods from the current context of the  object, and you can’t call Private methods with a receiver, even if that  receiver is 
self.
 Protected Methods 
Finally we have Protected methods. A Protected method is not  accessible from outside of the context of the object, but it is  accessible from inside the context of another object of the same type.
For example, imagine we have the following 
sku method on the 
Product class:
class Product
attr_accessor :name, :quantity
def initialize(name)
      @name = name
      @quantity = 1
puts "The SKU is #{sku}"
end
protected
      def sku
         name.crypt("yo")
      end
end
In this example we are generating a SKU from the product’s name.
As with the Private method example from earlier, this method is not accessible outside the context of the object:
milk = Product.new("Milk")
The SKU is yo.B6xygWtQ1w
=> 
milk.sku
NoMethodError: protected method 'sku' called for 
 
 
However, if you call the method with 
self it will work:
 
class Product
attr_accessor :name, :quantity
def initialize(name)
      @name = name
      @quantity = 1
puts "The SKU is #{self.sku}"
end
protected
      def sku
         name.crypt("yo")
      end
end
So a Protected class method can be called within the context of an object of the same type.
This means you can call Protected class methods of other objects inside an object of the same type. For example:
 
class Product
attr_accessor :name, :quantity
def initialize(name)
@name = name
@quantity = 1
end
def ==(other)
      self.sku == other.sku
 end
protected
      def sku
         name.crypt("yo")
      end
end
 
In this class we’ve implement the 
== method to assert equality between two objects. This method accepts another  Product object and will call the Protected 
sku method.
If the two Product objects have the same name, they will be considered equal:
milk1 = Product.new("Milk")
=> #
 
milk2 = Product.new("Milk")
=> #
 
bread = Product.new("Bread")
=> #
 
milk1 == bread
=> false
 
milk1 == milk2
yo
=> true
So the important thing to note here is, you can call Protected methods inside the context of an object of the same type.
Conclusion   
The differences between Public, Private and Protected methods can 
seem confusing at first, particularly the differences between Private 
and Protected methods.
Writing a clean and easy to use public interface for your objects is a
 very important part of the design process. The public API will say a 
lot about the object and how it should be used. It’s important to take 
care and ensure you make good choices when deciding on method names and 
what methods should be public.
The choice between Private and Protected will come down to how you intend your object to be used.
As with just about everything else in programming, learning via 
experience is really the only way to progress. If today’s tutorial 
seemed like a lot to take in, don’t worry about it. As long as you keep 
exploring, you will eventually find the way.
:::Happy hacker ;)