Solidity provides four ways to declare the visibility of a function and state variable in a contract. Here's a run through of all of them.
Private
Private state variables and functions , can only be called or referred to by the parent contract. External and child contracts have no access. The name private dosen't imply you should store sensitive info in state variables, everything on the blockchain is public. So avoid doing that to keep your app secure .
Internal
Similar to private , state variables and contracts cannot be called or referred to by external contracts, but the major difference is , child contracts have access to state variables and functions.
Public
This allows everyone ( external contracts , child contracts , e.t.c ) . To have access to state variables and functions. When declared as public , the compiler automatically generates getters , which allow other contracts to read their values.
External
This prevents the contract from being called from within . it can only be called by external contracts. This keyword cannot be applied on state variables. Trying to call an external contract from within , throws and error.