Создать набор классов java

Multiple classes in single file

I’m having trouble putting multiple classes into a single file. For example, when my file looks like:

public class FirstClass() <> public class SecondClass() <> public class ThirdClass() <> 

«My professor asked us to turn in our assignments in a single .class file to save him time.» — Your professor is encouraging bad habits and should know better .

Most of the answers implicitly address only multiple top-level classes per file. You can have multiple public classes defined in a single file — just not multiple top-level classes. Five years after this question was posted, I’ve added a correct, more complete answer.

8 Answers 8

One Java file can consist of multiple classes with the restriction that only one of them can be public. As soon as you remove public keyword from your classes, you can combine them into a single Java file.

«with the restriction that only one of them can be public«. I don’t think so. Take a look at Rectangle2D for example, it has two inner class, both are public.

@MadProgrammer : rectangle 2d does not contain a main function. If you have a main function in a class that function should be declared as public and the file should have the name of that public class. But if there is not main(), then you can have any number of classes as public, The OP’s class theaterdemo contains main().

Читайте также:  Java lang illegalargumentexception location bukkit

It makes no difference, you can have as many public inner classes as you like, they can even be static, but yes, the outer class containing the main method should public.

@Ashwin And of course someone’s edited the question just to remove that very important bit of info.

At the risk of spoon-feeding

import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; public class TheaterWindow extends JFrame < private JPanel pnlAdultTicketPrice, pnlAdultTicketsSold, pnlChildTicketPrice, pnlChildTicketsSold, pnlCalculate, pnlMain; private JLabel lblAdultTicketPrice, lblAdultTicketsSold, lblChildTicketPrice, lblChildTicketsSold; private JTextField txtAdultTicketPrice, txtAdultTicketsSold, txtChildTicketPrice, txtChildTicketsSold; private JButton btnCalculate; public TheaterWindow() < // Sets window title setTitle("Theater"); // Sets layout to BorderLayout setLayout(new GridLayout(5,1)); // Specifies what happens when close button is clicked setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Builds the panels buildPanels(); // Add the panels to the frame's content pane add(pnlAdultTicketPrice); add(pnlChildTicketPrice); add(pnlAdultTicketsSold); add(pnlChildTicketsSold); add(pnlCalculate); // Size the frame to fit all of the panels pack(); // Display the window setVisible(true); >private void buildPanels() < // Creates labels to display instructions lblAdultTicketPrice = new JLabel("Adult ticket price"); lblChildTicketPrice = new JLabel("Child ticket price"); lblAdultTicketsSold = new JLabel("Adult tickets sold"); lblChildTicketsSold = new JLabel("Child tickets sold"); // Creates text fields that are 10 characters wide txtAdultTicketPrice = new JTextField(10); txtChildTicketPrice = new JTextField(10); txtAdultTicketsSold = new JTextField(10); txtChildTicketsSold = new JTextField(10); // Creates button with caption btnCalculate = new JButton("Calculate"); // Adds action listener to button btnCalculate.addActionListener(new CalcButtonListener()); // Creates panels pnlAdultTicketPrice = new JPanel(); pnlChildTicketPrice = new JPanel(); pnlAdultTicketsSold = new JPanel(); pnlChildTicketsSold = new JPanel(); pnlCalculate = new JPanel(); pnlMain = new JPanel(); // Adds elements to their proper panels pnlAdultTicketPrice.add(lblAdultTicketPrice); pnlAdultTicketPrice.add(txtAdultTicketPrice); pnlChildTicketPrice.add(lblChildTicketPrice); pnlChildTicketPrice.add(txtChildTicketPrice); pnlAdultTicketsSold.add(lblAdultTicketsSold); pnlAdultTicketsSold.add(txtAdultTicketsSold); pnlChildTicketsSold.add(lblChildTicketsSold); pnlChildTicketsSold.add(txtChildTicketsSold); pnlCalculate.add(btnCalculate); // Adds all of the above panels to a main panel pnlMain.add(pnlAdultTicketPrice); pnlMain.add(pnlChildTicketPrice); pnlMain.add(pnlAdultTicketsSold); pnlMain.add(pnlChildTicketsSold); pnlMain.add(pnlCalculate); >private class CalcButtonListener implements ActionListener < public void actionPerformed(ActionEvent e) < // Creates object of Theater Theater theater = new Theater(); // Sets the member variables of Theater to the user's input theater.setAdultTicketPrice(Double.parseDouble(txtAdultTicketPrice.getText())); theater.setChildTicketPrice(Double.parseDouble(txtChildTicketPrice.getText())); theater.setAdultTicketsSold(Integer.parseInt(txtAdultTicketsSold.getText())); theater.setChildTicketsSold(Integer.parseInt(txtChildTicketsSold.getText())); // Creates DecimalFormat object for rounding DecimalFormat dollar = new DecimalFormat("#.##"); // Display the charges. JOptionPane.showMessageDialog(null, "Adult ticket gross: $" + Double.valueOf(dollar.format(theater.getAdultGross())) + "\n" + "Child ticket gross: $" + Double.valueOf(dollar.format(theater.getChildGross())) + "\n" + "Adult ticket net: $" + Double.valueOf(dollar.format(theater.getAdultNet())) + "\n" + "Child ticket net: $" + Double.valueOf(dollar.format(theater.getChildNet())) + "\n" + "Total gross: $" + Double.valueOf(dollar.format(theater.getChildGross())) + "\n" + "Total net: $" + Double.valueOf(dollar.format(theater.getTotalNet()))); >> public class Theater < private double PERCENTAGE_KEPT = 0.20; private double adultTicketPrice, childTicketPrice; private int adultTicketsSold, childTicketsSold; public double getAdultGross() < return getAdultTicketPrice() * getAdultTicketsSold(); >public double getAdultNet() < return PERCENTAGE_KEPT * getAdultGross(); >public double getAdultTicketPrice() < return adultTicketPrice; >public int getAdultTicketsSold() < return adultTicketsSold; >public double getChildGross() < return getChildTicketPrice() * getChildTicketsSold(); >public double getChildNet() < return PERCENTAGE_KEPT * getChildGross(); >public double getChildTicketPrice() < return childTicketPrice; >public int getChildTicketsSold() < return childTicketsSold; >public double getTotalGross() < return getChildGross() + getAdultGross(); >public double getTotalNet() < return getChildGross() + getChildNet(); >public void setAdultTicketPrice(double adultTicketPrice) < this.adultTicketPrice = adultTicketPrice; >public void setAdultTicketsSold(int adultTicketsSold) < this.adultTicketsSold = adultTicketsSold; >public void setChildTicketPrice(double childTicketPrice) < this.childTicketPrice = childTicketPrice; >public void setChildTicketsSold(int childTicketsSold) < this.childTicketsSold = childTicketsSold; >> > 

Источник

Познаём Java. Вторая чашка: собираем классы в кучки. Пробуем апплеты

Как вы уже слышали, Java проектировалась с рассчётом на совместимость со всем, чем только можно. Такое ограничение вынудило разработчиков Java сделать её такой, чтобы максимально упростить развёртывание приложений, при этом обеспечив логическую стройность языка.

Как происходит загрузка классов?

Для того, чтобы найти класс по имени когда вы его вызываете, в Java существует стандартный загрузчик классов. Он оперирует понятием classpath. Список classpath — это набор путей, где следует искать файлы классов. Каждый classpath может указывать как на директорию, так и на так называемый jar-файл (зазипованная директория со скомпилированными .class’ами и разрешением .jar, типа «йА java-archive!»). По умолчанию в classpath входят файлы стандартных библиотек и директория, из которой вы вызвали саму Java. Именно таким образом был найден класс HelloWorld — java нашла файл HelloWorld.class и запустила в нём метод main. Собственно, так и работают большинство программ, даже самых сложных. Всё начинается с одного main’а…

Пакеты классов

Пакет (package) представляют собой набор классов, объединённых по смыслу. Пакеты обычно вкладываются друг в друга, образуя собо иерархию, дающую понять, что зачем. На файловой системе такая иерархия выглядит в виде вложенных друг в друга директорий с исходниками. Так, исходники пакета a лежат в папке a, исходники пакета a.b — в папке a/b и так далее. Типичный путь к пакету выглядит примерно так:
org.apache.commons.collectons . Видите, сразу ясно зачем он нужен. Чтобы использовать какой-то класс в коде другого класса, вы должны импортировать его, написав до объявления класса строку
import путь.к.классу.ИмяКласса;
Кроме того, если вы используете классы одного пакета часто, вы можете импортировать весь пакет:
import путь.к.классу.*;
Это относится ко всем пакетам, кроме java.lang — он импортирован по умолчанию, именно из него были в прошлом примере взяты классы System и String. На самом деле они лежат в некоем jar’е, в каталоге java/lang.

Что ж, теперь вы знаете как работает загрузчик классов. В реальных проектов количество classpath измеряется десятками, а то и сотнями.

Организация кода

Если вы пишете свои первые маленькие примерчики и вам лень создавать иерархию классов — пусть, это ваше право. Но помните, в серьёзном проекте вы всегда должны будете разложить свои классы по пакетам. Обычно корневые пакеты создаются такими, чтобы ясно давать понять кто автор кода, и к чему он относится.
Например:
ru.vasiapupkin.photomaker выбирается корневым пакетом
ru.vasiapupkin.photomaker.core сюда мы пишем классы отвечающие за логику
ru.vasiapupkin.photomaker.visual сюда, допустим, все наши окошки приложения

и так далее.
Чтобы создать класс
ru.vasiapupkin.photomaker.Starter
вы должны:
создать файл Starter.java в папке ru/vasiapupkin/photomaker/
прописать в нём первой строчкой (точнее говоря, до импортов)
package ru.vasiapupkin.photomaker;

Коллижн

«А что будет, если у нас будет два класса с одним именем?», — спросите вы. «Смотрите», — отвечу я.
Допустим вы решили что вы умнее джавы и создали свой класс строки — String. Но вот проблема, у нас же уже есть такой!
Значит, вам придётся положить свой класс в пакет, скажем ru.vp.stuff и обращаться к нему так: ru.vp.stuff.String.
Именно поэтому не рекомендуется класть классы прямо в корень classpath — таким образом вы роете себе дорогу к несовместимости, ведь Java требует, чтобы каждый класс определялся однозначно. Именно поэтому нельзя написать так:
import ru.vp.SuperClass;
import ru.mashka.SuperClass;
За это вас накажет компилятор, потому что он не будет знать, какой из них использовать.
Мораль: правильно выбирайте и имя класс и имя пакета.

Погоняем?

Давайте улучшим первое приложение. Эх, классика интернета… Создадим апплет.

Эх, может быть апплетами.

import java.applet.Applet ;
import java.awt.Graphics ;

public class HelloWorld extends Applet

public void paint( Graphics g) g.drawString( «Hello World» ,15,15);
>

>

* This source code was highlighted with Source Code Highlighter .

Так, что у нас тут? Импортировано 2 класса, один из них — стандартный пустой апплет, который мы будем расширять. Второй — Graphics. Graphics — это понятие из библиотеки AWT. Кстати, небольшой экскурс. AWT (Abstract Window Toolkit) входил ещё в первую Java и был предназначен для многих задач, связанных в основном с отображением.
Так вот, объект типа Graphics позволяет нам рисовать на себе всякую муру типа строк, линий, кружочков и прочего. В данном примере мы написали строчку с отступом.
Метод paint здесь написан не от балды — он перекрывает аналогичный метод класса Applet, и когда java будет перерисовывать этот конкретный апплет, она вызовет этот метод.

Посмотреть на наш апплет достаточно просто — пишем небольшой HTML:

… а может приложением.

Давайте попробуем сделать HelloWorld в standalone-приложении.

import java.awt.* ;
import javax.swing.* ;
public class HelloWorld extends JFrame

public static void main( String [] args) new HelloWorld();
>

add( new JLabel( «Hello world» ));
setSize(200,200);
setVisible( true );
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
>
>

* This source code was highlighted with Source Code Highlighter .

Здесь мы полностью импортируем основные классы пакетов Swing и AWT. Swing — более поздняя чем AWT библиотека, сейчас именно она обеспечивает отображение основной части графического интерфейса для Java-приложений.
Итак, в main мы просто создаём экземпляр класса HelloWorld.
Сейчас наш класс наследуется от класса JFrame. Это класс из Swing, он представляет собой окно, которое отображается пока не будет закрыто.
Блок <. >— это «общий конструктор». Он добавляется к любому конструктору нашего класса. Так как у нас нет ни одного — он добавляется к пустому конструктору без параметров, который создаётся на лету, если у класса нет ни одного.
Мы добавляем на окно новый объект типа JLabel (т.е. надпись), затем устанавливаем окну размеры и отображаем его. Последняя строчка нужна, чтобы выполнение приложения закончилось, когда будет закрыто окно. Таким образом, вы можете быть уверены что после закрытия окна у вас в памяти не останется висеть ваше приложение.
Запускать его нужно точно так же как и прошлое: пишем, компилируем, запускаем.

А может и сервлетами? Наверное, потом.

В этих двух статьях я постарался дать вам начальное представление о возможностях Java в общем. За рамками сегодняшней статьи (наверное, будут в завтрашней) остались сервлеты и прочие радости серверной части типа JSP-страниц, а также МИДлеты — приложения для мобилок. Я бы мог рассмотреть и то и то, но хотел бы знать, чего больше хотят читатели. Кроме того, возможно, нужно рассказать о самых основах языка. Примерно на том же уровне подробности, что и начало этой статьи. Напишите в комментариях, какую статью вы хотели бы видеть в следующий раз:
— классы и интерфейсы: ООП в джаве;
— буквы-цифры-строчки: работа с базовыми типами;
— создание оконных приложений с помощью Swing;
— от мала до велика: сервлеты, мидлеты и 2 слова о портлетах.

Когда отпишетесь — станет ясно, куда копать дальше. Всем спасибо за внимание.

Ссылка для тех, кому лень ждать завтра: основы языка (eng.).

Источник

Как создать массив разных классов?

У меня такая задача что в ней нужно как то закинуть мои классы а их 5 штук в массив. После этого производится некая операция которая решает какие классы нужны. в итоге из 5 будут только 2 или 3. И главное не попорядку. А Б В Г Д. Может быть так что мне нужны будут только А В Д, Или Б В Д. Или А Д. Единственное решение для меня это добавить мои классы в массив но не создавать их. Тобишь должно быть так. mas[]=; и т.д. Чтобы после я сделал так new mas[0]; Можно ли сие чудо как нибудь реализовать в программном виде?

А вот нас в школе учили, что класс — это один из множества абстрактных типов данных в ООП, а объект — это экземпляр класса. Поэтому «классы закидывать в массив» как-то некорректно 😉

@InterfaceUnknown, Дак я же класс не добавляю в массив)), Я имя добавлю Чтобы потом запустить тот или иной класс. Ведь код то у меня динамический. Был бы статическим я бы switch испольовал и все дела.

1 ответ 1

Вариант 1: в лоб

В массив кладём объекты классов:

После выбора нужного класса создаём его экземпляр через Reflections API:

Сlass clazz = classes[index]; Constructor defaultConstructor = clazz.getDeclaredConstructor(); Object obj = defaultConstructor.newInstance(); 

Плюс этого метода — краткость. Минусы — отсутствие гибкости (создание объектов только через конструктор по умолчанию, невозможность кастомизации процесса создания), скорость (Reflections API достаточно медленный, если вы будете создавать таким методом большое количество объектов — вы это почувствуете).

Вариант 2: фабрики

Реализуем шаблон проектирования «Фабричный метод». Для этого создаём класс ObjectFactory :

public abstract class ObjectFactory < // Метод createObject должен возвращать общего предка всех создаваемых классов. // Так как вы ничего не сказали о своей иерархии, // я для приера взял Object как предка всех классов в Java. public Object createObject(); >

Для каждого класса, который необходимо создать, создаём наследника ObjectFactory , создающего экземпляр этого класса:

public class AFactory extends ObjectFactory < public Object createObject() < A a = new A(); // дополнительные манипуляции по созданию экземпляра класса A return a; >> public class BFactory extends ObjectFactory < public Object createObject() < B b = new B(); // дополнительные манипуляции по созданию экземпляра класса B return b; >> . 

Выбрав нужную фабрику, создаём объект нужного класса:

ObjectFactory factory = factories[index]; Object obj = factory.createObject(); 

Плюсы: отсутствие требований к конструкторам создаваемых классов и возможность настройки процесса создания объектов. Минус: больший объём кода по сравнению с первым методом.

Наиболее предпочтительным является второй метод, так как он даёт больше контроля над процессом создания экземпляров классов.

Источник

Оцените статью