About the most important thing when using an OO language is that objects model behaviour and, where possible, contain the data required to implement the behaviour. Behaviour is what the objects do, not what is done to them.
So unless there is a reason to in a requirement you haven't stated, the cell itself doesn't have any behaviour, it is just a place that the players mark.
So you could have a simple array of marks that both players update, with an enum with three values, or you could have each player update their own data of the marks they have made, in which case each player would have either a boolean array or a short bit mask to indicate their goes. In the latter case, each player then only changes the state of their own 'goes' and can implement the test for their winning condition rather than having shared state - the only sharing is they have to ask the other player whether the chosen cell is valid. It depends how strictly OO you want your design to be as to whether this is 'best practice' or not - for such a simple problem you could write in COBOL and the users would be as happy.