Deklaracja metody liczPole() powinna znajdować się w klasie bazowej, czyli w tym przypadku w klasie „figura”. To podejście jest zgodne z zasadami programowania obiektowego i tzw. polimorfizmem. Dzięki temu każda klasa dziedzicząca po „figurze” jest zobowiązana do własnej implementacji tej metody. To bardzo praktyczne rozwiązanie, bo umożliwia tworzenie ogólnych kolekcji (np. List<Figura>), które mogą przechowywać obiekty różnych figur, a następnie wywoływać liczPole() na każdym z nich bez zastanawiania się, jakiego typu to dokładnie obiekt. Z mojego doświadczenia wynika, że tak właśnie projektuje się API i biblioteki geometryczne – klasa bazowa narzuca kontrakt, a szczegóły są po stronie konkretnych figur. Warto dodać, że zgodnie z dobrymi praktykami, do deklarowania takich metod używa się słowa kluczowego „abstract”, co jasno komunikuje, że metoda musi być uzupełniona w klasach potomnych. Takie podejście mocno ułatwia rozbudowę kodu, np. kiedy chcemy dodać nowy typ figury, wystarczy, że nadpiszemy liczPole(). Moim zdaniem to jeden z najfajniejszych przykładów, jak dobrze przemyślana architektura kodu oszczędza czas i nerwy programistom.
Częstym błędem przy projektowaniu hierarchii klas figur geometrycznych jest umieszczanie kluczowych metod, takich jak liczPole(), w zbyt szczegółowych klasach, np. w klasie trapez, czworokąt czy trójkąt. To prowadzi do powielania kodu oraz utrudnia późniejszy rozwój aplikacji. Jeżeli metoda liczPole() znalazłaby się w którejś z tych klas, to każda z nich miałaby własną, niezależną implementację, bez jednego, wspólnego punktu odniesienia. Zdarza się, że osoby początkujące traktują każdą figurę z osobna, próbując umieścić jej logikę tylko w konkretnej klasie, ale to prosta droga do chaosu i dublowania kodu. Standardy branżowe i literatura przedmiotu (np. wzorce projektowe GoF) jasno wskazują, że w takich przypadkach warto korzystać z tzw. abstrakcji – czyli deklarować abstrakcyjną metodę w klasie bazowej, a implementować ją w klasach potomnych. Pozwala to na spójność interfejsu i wykorzystanie polimorfizmu – kluczowej cechy nowoczesnych języków obiektowych. Umieszczając liczPole() na poziomie np. czworokąta, tracimy możliwość wymuszania implementacji tej metody w innych figurach, jak trójkąt czy koło, co jest poważnym ograniczeniem. Także z praktycznego punktu widzenia – gdyby kod miał być rozwijany przez większy zespół albo miał być podstawą do dalszych rozszerzeń (np. nowe typy figur), to scentralizowana deklaracja metody w klasie figura jest rozwiązaniem najbezpieczniejszym, najbardziej elastycznym i najłatwiejszym w utrzymaniu. Praktyka pokazuje, że trzymanie się tych zasad po prostu się opłaca i minimalizuje potencjalne błędy w przyszłości.