אז ככה:
1. ב-Java יש שני סוגים של טיפוסים:
טיפוסים "פרימיטיביים" כמו int, char, double וטיפוסי ייחוס (reference) שהם למעשה אובייקטים, כגון String או כל מחלקה שתכתוב בעצמך.
 
במקרה של טיפוסים פרימיטיביים, השיטה אכן חייבת להחזיר אותו טיפוס בדיוק כדי להיות override.
במקרה של אובייקטים, ניתן "לצמצם" את הטווח, ולהחזיר טיפוס של מחלקה יורשת.
 
אבל כמובן בשום מקרה אי אפשר לשנות לחלוטין את הטיפוס המוחזר למשהו לא קשור.
 
2. ב-Java יש 3 סוגי "טווח גישה" על איברי מחלקה ומתודות:
1. private - זה איבר (או מתודה) פרטי שניתן לגשת אליו רק מתוך המחלקה עצמה.
אפילו מחלקה יורשת לא יכולה לראות אברים שהם private של מחלקת האב שלה.
וזו הסיבה שתשובה ד' נפסלת.
 
2. protected - איבר או מתודה שזמינה מתוך המחלקה עצמה וזמינה גם למחלקות יורשות. ועל זה מדברת תשובה ב'.
 
3. public - איבר או מתודה שזמינים לגישה של כל אחד. זה הפרט שחסר בתשובה ב':
מן הסתם, מחלקה יורשת יכולה לגשת לכל מה ש-public בנוסף לכל מה ש-protected.
 
למעשה, הפירוט למעלה קצת מופשט ולא לגמרי מדויק.
ב-Java גם מחלקות שאינן יורשות ממחלקה מסוימת אבל נמצאות איתה באותה חבילה יכולות לגשת לאיברים שהם protected.
ויש גם "טווח גישה" רביעי - package private שאין לו מילת סימון בקוד בכלל, והוא יוצר מצב מוזר בו מחלקה יורשת לא רואה את האיבר (או המתודה) אבל מחלקה לא קשורה מאותה חבילה כן.
 
יש טבלה נחמדה בקישור הזה:
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html