#java #android #классы
Здравствуйте. Есть три класса. Обычный, абстрактный и наследник абстрактного. Обычный класс содержит переменную абстрактного, куда после неких манипуляций запишется объект наследника. Абстрактный: public abstract class LessonInfo { static String NAME; static int COUNT_QUESTION; static int[] PARTS; static String[] INFO_QUESTIONS; static int[] MARK_QUESTIONS; } Наследник: public class RussianInfo extends LessonInfo { static final String NAME = "Русский язык"; static final int COUNT_QUESTION = 24; static final int[] PARTS = {24}; static final String[] INFO_QUESTIONS = {"Определение главной информации текста", "Средства связи предложений", "Лексическое значение слова", "Постановка ударения", "Употребление паронимов", "Морфологические нормы", "Синтаксические нормы", "Правописание корней", "Правописание приставок", "Правописание суффиксов", "Правописание глаголов и причастий", "Правописание НЕ и НИ", "Слитное и раздельное написание слов", "Правописание -Н- и -НН_", "Пунктуация", "Обособленные члены предложения", "Пунктуация во второстепенных чл. предложения", "Пунктуация в СПП", "Пунктуация в разых тижах связи", "Смысловая целостность текста", "Функционально-смысловые типы речи", "Лексическое значение слова", "Средства связи предложений", "Средства выразительности" }; static final int[] MARK_QUESTIONS = {2,1,1,1,1,1,7,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,25}; } Обычный (фрагмент): public class TestActivity extends AppCompatActivity { LessonInfo info; static LessonInfo lessonInfo; @Override protected void onCreate(Bundle savedInstanceState) { lessonInfo = new RussianInfo(); } } После команды "ОбычноеАктивити.lessonInfo.MARK_QUESTIONS[i]" приложение не вылетает. Что не так? Думаю, накосячил с абстрактным классом и его наследником
Ответы
Ответ 1
Попробуй в абстрактном классе создать абстрактный метод initVariables и вызвать его в конструкторе абстрактного класса. В каждом из наследников реализовывать этот метод и инициализировать переменные именно в нем. Так же, не стоит в абстрактном классе переменные делать static, так как значение этой переменной будет одинаково для всех экземпляров класса. Абстрактный: public abstract class LessonInfo { public String name; public int countQuestion; public int[] parts; public String[] infoQuestions; public int[] markQuestions; public LessonInfo() { initVariables(); } public abstract void initVariables(); } Наследник: public class RussianInfo extends LessonInfo{ @Override public void initVariables() { name = "Русский язык"; countQuestion = 24; parts = new int[]{24}; infoQuestions = new String[]{"Определение главной информации текста", "Средства связи предложений", "Лексическое значение слова", "Постановка ударения", "Употребление паронимов", "Морфологические нормы", "Синтаксические нормы", "Правописание корней", "Правописание приставок", "Правописание суффиксов", "Правописание глаголов и причастий", "Правописание НЕ и НИ", "Слитное и раздельное написание слов", "Правописание -Н- и -НН_", "Пунктуация", "Обособленные члены предложения", "Пунктуация во второстепенных чл. предложения", "Пунктуация в СПП", "Пунктуация в разых тижах связи", "Смысловая целостность текста", "Функционально-смысловые типы речи", "Лексическое значение слова", "Средства связи предложений", "Средства выразительности"}; markQuestions= new int[]{2,1,1,1,1,1,7,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,25}; } } Активити: public class MainActivity extends AppCompatActivity { private LessonInfo lessonInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lessonInfo = new RussianInfo(); Log.d("MainActivity", "lessonInfo.name" + lessonInfo.name); Log.d("MainActivity", "lessonInfo.markQuestions" + lessonInfo.markQuestions.toString()); Log.d("MainActivity", "lessonInfo.infoQuestions" + lessonInfo.infoQuestions.toString()); } } Кстати, переменной lessonInfo тоже не нужно ставить модификатор static.Ответ 2
Еще один вариант: Абстрактный: public abstract class LessonInfo { public abstract String getName(); public abstract int getCountQuestion(); public abstract int[] getParts(); public abstract String[] getInfoQuestions(); public abstract int[] getMarkQuestions(); } Наследник: public class RussianInfo extends LessonInfo { private String name = "Русский язык"; private int countQuestion = 24; private int[] parts = new int[]{24}; private String[] infoQuestions = new String[]{"Определение главной информации текста", "Средства связи предложений", "Лексическое значение слова", "Постановка ударения", "Употребление паронимов", "Морфологические нормы", "Синтаксические нормы", "Правописание корней", "Правописание приставок", "Правописание суффиксов", "Правописание глаголов и причастий", "Правописание НЕ и НИ", "Слитное и раздельное написание слов", "Правописание -Н- и -НН_", "Пунктуация", "Обособленные члены предложения", "Пунктуация во второстепенных чл. предложения", "Пунктуация в СПП", "Пунктуация в разых тижах связи", "Смысловая целостность текста", "Функционально-смысловые типы речи", "Лексическое значение слова", "Средства связи предложений", "Средства выразительности"}; private int[] markQuestions = new int[]{2,1,1,1,1,1,7,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,25}; @Override public String getName() { return name; } @Override public int getCountQuestion() { return countQuestion; } @Override public int[] getParts() { return parts; } @Override public String[] getInfoQuestions() { return infoQuestions; } @Override public int[] getMarkQuestions() { return markQuestions; } } Активити: public class MainActivity extends AppCompatActivity { private LessonInfo lessonInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lessonInfo = new RussianInfo(); Log.d("MainActivity", "lessonInfo.name" + lessonInfo.getName()); Log.d("MainActivity", "lessonInfo.markQuestions" + lessonInfo.getMarkQuestions().toString()); Log.d("MainActivity", "lessonInfo.infoQuestions" + lessonInfo.getInfoQuestions().toString()); } }Ответ 3
В Java полиморфизм работает только у нестатических методов. Статические поля и методы не наследуются, а класс, поле которого будет использовано, вычисляется на этапе компиляции, по типу выражения слева от точки (в вашем случае LessonInfo). Сходным образом работает обращение к полям, объявленным с одним именем в суперклассе и в наследнике. Если хочется сделать настройки через наследование, а не, например, через конфигурационные файлы, можно сделать как-то так: public abstract class LessonInfo { public String name(); public int questionCount(); public int[] parts(); public String[] infoQuestions(); public int[] markQuestions(); } public class RussianInfo extends LessonInfo { @Override public String name() { return "Русский язык"; } /* ..... */ @Override public String[] infoQuestions(); return new String[] {"Определение главной информации текста", "Средства связи предложений", "Лексическое значение слова", "Постановка ударения", "Употребление паронимов", "Морфологические нормы", "Синтаксические нормы", "Правописание корней", "Правописание приставок", "Правописание суффиксов", "Правописание глаголов и причастий", "Правописание НЕ и НИ", "Слитное и раздельное написание слов", "Правописание -Н- и -НН_", "Пунктуация", "Обособленные члены предложения", "Пунктуация во второстепенных чл. предложения", "Пунктуация в СПП", "Пунктуация в разых тижах связи", "Смысловая целостность текста", "Функционально-смысловые типы речи", "Лексическое значение слова", "Средства связи предложений", "Средства выразительности" }; } } Использование: public class TestActivity extends AppCompatActivity { LessonInfo info; @Override protected void onCreate(Bundle savedInstanceState) { info = new RussianInfo(); System.out.println( Arrays.toString( info.infoQuestions() ) ); } }
Комментариев нет:
Отправить комментарий