An additional form of encapsulation using inheritance and interfaces is type checking. We can check an object's type at any level of inheritance or for any interface they might have.
Right now the custodian has a method where they loop through their list of foods and the food is eaten. But we have a problem, the custodian has to carry kibble with them as well and if we called this method he would end up eating animal food as well.
We aren't cruel so let's fix that. Anything that is a human food implements the IHumanFood interface so knowing that we can check to see if each Food object is a certain type of object.
Now when HaveSnack is executed the method will skip over the CheetahKibble because it is not a type of IHumanFood. We've just saved the custodian from having a terrible day.
We also have an issue if we have an object that is an interface type and we need to do something related to a specific type. Let's take a look at a method the custodian has that returns the first ICleanable in their list.
The list contains two types of things: a Booth type and a Restroom type. When we catch the return and use the object we can see that we only have ICleanable things that we can do with it.
Our custodian doesn't want to get their hands too dirty right now so they don't care about the Restroom, but if it's a Booth type they want to dust it. The only problem is we don't know what kind of type is being returned and if we try to force it to be a type of Booth we will get a null reference exception because the object returned is a Restroom type and can't be cast as a Booth.
So what we can do is add a conditional statement that checks if the cleanable object is a Booth type and if it is cast it to the Booth type so we can call DustCounter. As you can see the check failed gracefully.