It makes sense for the monster to check the player’s shield when it attacks, because that’s what the monster is doing in the simulation. It makes sense for the player object to have a shield object, because that’s exactly the situation you intend to represent. You could have a public member function on the player for getting a read-only view of their equipment—then monsters could use those methods to answer questions like “Does the player have a shield, and is it wooden?” but wouldn’t be able to alter that information in unstructured ways.
An interaction like this can be modelled in many ways. It’s up to you to start with something plausible, and alter it when you see the need to. And you can’t really predict the choices you will make in the future, so it doesn’t make sense to write much more than just what gets the job done well in the present and is easy enough to change later.
OOP is a class of architectural philosophies, not a consistent theory with specific or consistent rules, so there is no “right answer” here. You just have to develop a sense of design aesthetics over time. One good way to do that is to have other developers review your code and point out areas for improvement. But I would say correctness by construction is a very strong guideline.