大家好。在本主题中,我想详细讨论 Java 类及其类型,以帮助初学者理解本主题,或许非新手也能学到新东西。在可能的情况下,所有内容都将使用现实生活中的示例以及随附的代码示例来显示。让我们开始吧。 我想指出的是,主要的是了解前两种类型的类,本地类和匿名类只是内部类的子类型。
什么是班级?
类是某事物的逻辑描述,是一个模板,您可以使用它创建该事物的真实实例。换句话说,它只是对创建的实体应该是什么样子的描述:它们应该具有什么属性和方法。 属性是实体的特征,方法是实体可以执行的操作。现实生活中类的一个很好的例子可以被认为是绘图,它可以帮助您理解什么是类:绘图用于描述结构(弹射器、螺丝刀),但绘图不是设计。正如工程师使用蓝图来创建设计一样,编程使用类来创建描述属性和方法的对象。public class Student {
private String name, group, specialty;
public Student(String name, String group, String specialty) {
this.name = name;
this.group = group;
this.specialty = specialty;
}
// getters/setters
}
在此示例中,我们创建了一个描述“学生”实体的 Java 类:每个学生都有一个姓名、小组和专业。现在,在程序的其他地方,我们可以创建此类的真实示例。换句话说:如果班级Student
是学生应有的形象,那么创建的实例就是实际的学生本身。创建新学生的示例:new Student("Ivan", "KI-17-2", "Computer Engineering");
操作符new
搜索类Student
,然后调用该类的特殊方法(构造函数)。构造函数返回一个现成的类对象Student
- 我们亲爱的、饥饿的没有奖学金的学生:))
Java 中的类类型
在 Java 中,有 4 种类包含在另一个类中:-
嵌套内部类是外部类内部的非静态类。
-
嵌套静态类是外部类内部的静态类。
-
Java 本地类是方法内的类。
-
匿名 Java 类是动态创建的类。
外部类中的非静态类
首先,我想让你通过一个真实的例子来理解这是什么,因为这样更容易理解。所以现在我们将把一个真正的大东西分解成更小的部件,我们将拆解一架飞机!然而,为了举例,展示一点就足够了;我们不会完全分解它。为了形象化这个过程,我们将使用飞机图。 首先,我们需要创建一个类,Airplane
在其中添加一些描述:飞机名称、识别码、航班。
public class Airplane {
private String name, id, flight;
public Airplane(String name, String id, String flight) {
this.name = name;
this.id = id;
this.flight = flight;
}
// getters/setters
}
现在我们要添加翅膀。创建一个单独的类?如果我们有一个复杂的飞机设计程序,并且需要创建大量的派生类(与父类具有相同逻辑的类,即它们继承的类,但所以他们通过添加逻辑或更详细的特征来扩展父类),但是如果我们只有一个只有一架飞机的游戏怎么办?那么我们把整个结构放在一个地方(一个类)完成会更加合理。这就是非静态嵌套类发挥作用的地方。本质上,这是对我们外部类的一些细节的更详细的描述。在此示例中,我们需要为飞机创建机翼 - 左翼和右翼。让我们一起创造吧!
public class Airplane {
private String name, id, flight;
private Wing leftWing = new Wing("Red", "X3"), rightWing = new Wing("Blue", "X3");
public Airplane(String name, String id, String flight) {
this.name = name;
this.id = id;
this.flight = flight;
}
private class Wing {
private String color, model;
private Wing(String color, String model) {
this.color = color;
this.model = model;
}
// getters/setters
}
// getters/setters
}
Wing
因此,我们在类(飞机)内 创建了一个非静态嵌套类(翼) Airplane
,并添加了两个变量 - 左翼和右翼。每个翅膀都有自己可以更改的属性(颜色、型号)。这样您就可以根据需要为建筑物配备人员。注意:前面的图上有相当多的飞机部件,事实上,我们可以将所有部件划分为内部类,但这样的过程并不总是可取的。需要根据任务来追踪此类时刻。您可能根本不需要翅膀来解决问题。那么就没有必要做它们了。这就像将一个人切成腿、手臂、躯干和头部 - 这是可能的,但为什么如果这个类仅用于存储有关人的数据呢? 非静态嵌套Java类的特点:
- 它们仅存在于对象中,因此要创建它们,您需要一个对象。换句话说:我们将机翼设计为飞机的一部分,因此要创建机翼,我们需要飞机,否则我们不需要它。
- Java 类中不能有静态变量。如果您需要一些常量或其他静态内容,则需要将它们移至外部类。这是由于非静态嵌套类与外部类的紧密耦合所致。
- 该类可以完全访问外部类的所有私有字段。此功能有两种工作方式。
- 您可以获得对外部类实例的引用。示例:Airplane。这是飞机的链接,这是机翼的链接。
外部类中的静态类
这种类型的类与常规外部类没有什么不同,除了一件事:要创建此类类的实例,您需要列出从外部类到所需外部类的整个路径,并用点分隔。例如:Building.Plaftorm platform = new Building.Platform();
静态类用于将相关类并排放置,以便逻辑结构更易于使用。例如:我们可以创建一个外部类Building
,其中会有代表特定建筑物的特定类列表。
public abstract class Building {
private String name, address, type;
Building(String name, String address) {
this.name = name;
this.address = address;
}
public static class Platform extends Building {
public Platform(String name, String address) {
super(name, address);
setType("Platform");
}
// some additional logic
}
public static class House extends Building {
public House(String name, String address) {
super(name, address);
setType("House");
}
// some additional logic
}
public static class Shop extends Building {
public Shop(String name, String address) {
super(name, address);
setType("Shop");
}
// some additional logic
}
// getters/setters
}
此示例演示静态类如何允许您将逻辑结构打包为更方便的形式。如果它们不存在,我们将需要创建 4 个完全不同的类。 这种方法的优点:
- 班级数量减少了。
- 所有类都位于其父类内。我们能够跟踪整个层次结构,而无需单独打开每个类。
- 我们可以参考Building类,IDE已经提示了该类所有子类的完整列表。这将使您更容易找到所需的课程,并更全面地展示整个情况。
Building.Shop myShop = new Building.Shop(“Food & Fun!”, “Kalyaeva 8/53”);
我还想指出,此策略在 AWT 2D 类中用于描述形状,例如 Line2D、Arc2D、Ellipse2D 等。
本地课程
这些类在其他方法中声明。事实上,它们具有非静态嵌套类的所有属性,只是它们的实例只能在方法中创建,并且该方法不能是静态的(要创建它们,您需要一个外部类的实例,对调用对象的实例隐式传递给非静态方法,并且在静态方法中没有此链接的方法)。 但他们也有各自的特点:- 本地类只能使用最终方法变量。问题是,本地类的实例可以在方法完成后存储在堆中,并且可以删除变量。如果该变量被声明为final,则编译器可以保存该变量的副本以供对象稍后使用。还有一件事:从 Java 8+ 版本开始,您可以在本地类中使用非最终变量,但前提是它们不会改变。
- 局部类不能用访问修饰符声明。
- 本地类可以访问方法变量。
Person
(假设这是一个人),其属性为street
(街道)、house
(房屋)。我们想返回一些对象来访问该人的位置。为此,我们创建了 AddressContainer 接口,该接口意味着存储有关人员位置的数据。
public class Person {
private String name, street, house;
public Person(String name, String street, String house) {
this.name = name;
this.street = street;
this.house = house;
}
private interface AddressContainer {
String getStreet();
String getHouse();
}
public AddressContainer getAddressContainer() {
class PersonAddressContainer implements AddressContainer {
final String street = Person.this.street, house = Person.this.house;
@Override
public String getStreet() {
return this.street;
}
@Override
public String getHouse() {
return this.house;
}
}
return new PersonAddressContainer();
}
public static void main(String[] args) {
Person person = new Person("Nikita", "Sholohova", "17");
AddressContainer address = person.getAddressContainer();
System.out.println("Address: street - " + address.getStreet() + ", house - " + address.getHouse());
}
// getters/setters
}
正如你所看到的,在方法内部,我们创建了一个类来实现人员位置的存储,在那里创建了常量变量(以便在退出方法后,变量被存储在一个对象中),并实现了一个用于获取地址和位置的方法。房子。现在我们可以在程序的其他地方使用这个对象来获取一个人的位置。我知道这个例子并不理想,简单地把 getter 留在类中会更正确Person
,但是,已经显示了这个类的创建及其可能的用途,然后就由你决定了。
匿名类
在幕后,匿名类只是常规的非静态嵌套类。它们的特点是易于使用。您可以在创建另一个类的实例时直接编写您的类。public class Animal {
public void meow() {
System.out.println("Meow!");
}
public static void main(String[] args) {
Animal anonTiger = new Animal() {
@Override
public void meow() {
System.out.println("Raaar!");
}
};
Animal notAnonTiger = new Animal().new Tiger();
anonTiger.meow(); // будет выведено Raaar!
notAnonTiger.meow(); // будет выведено Raaar!
}
private class Tiger extends Animal {
@Override
public void meow() {
System.out.println("Raaar!");
}
}
}
本质上,我们只是将两件事组合在一个地方:创建一个类的实例 ( Animal
) 并创建其继承者内部类的实例 ( Tiger
)。否则,我们需要单独创建类并使用更长的构造来实现相同的结果。 在许多情况下,使用匿名类是合理的,特别是在以下情况下:
- 班级体很短;
- 仅需要该类的一个实例;
- 该类在创建它的地方或在创建它之后立即使用;
- 类名并不重要,也不会让代码更容易理解。
JButton b2 = new JButton("Click");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Кнопка нажата!");
}
});
然而,在 Java 8 之后,他们开始使用 lambda 表达式,但仍然有很多代码是在版本 8 之前编写的,您可能会遇到(并且在 JavaRush 培训期间也会遇到)这样的铭文。\ 与 lambda 类似:
JButton b2 = new JButton("Click");
b2.addActionListener(e -> System.out.println("Кнопка нажата!"));
文章结束 感谢大家的关注,我希望您学到一些新的东西或理解一些您以前不理解的东西。我还想澄清一下,这篇文章属于“注重细节”类别。这是我的第一篇作品,所以我希望它对某人有用。在不久的将来,当新的想法出现时,我会尝试写点别的东西,我只有一个想法......祝大家好运,编程成功:)
GO TO FULL VERSION