Ada中如何实现类似Java instanceof的标记类型比较?
instanceof Great question! I totally get why you'd look for an Ada equivalent to Java's instanceof—it's a common pattern when working with object-oriented code. Let's break down how to do this properly in Ada, since the syntax is a bit different from what you tried with is in.
First, a quick key point: Ada's object-oriented model relies on tagged types (the equivalent of Java classes). To check an object's dynamic type (the actual type it was instantiated as, not just its static declared type), you need to use either the in operator with a 'Class type marker, or the Is_A attribute.
1. Using in with 'Class (Most Similar to instanceof)
This is the closest match to Java's instanceof. The T'Class syntax refers to the entire class hierarchy rooted at type T—so checking object in T'Class verifies if the object's dynamic type is T or any type derived from T.
Here's a direct equivalent to your Java Peach example:
with Ada.Text_IO; use Ada.Text_IO; procedure Check_Peach_Type is -- Define a tagged type (Ada's version of a class) type Peach is tagged null record; -- Declare an object, using Peach'Class to allow polymorphic assignment My_Peach : Peach'Class := Peach'(null record); begin -- Check if My_Peach is part of the Peach class hierarchy if My_Peach in Peach'Class then Put_Line("peach is of type Peach!"); end if; end Check_Peach_Type;
To compile and run this (using GNAT, Ada's most common compiler):
gnatmake check_peach_type.adb ./check_peach_type
You’ll see the expected output in your terminal.
2. Using the Is_A Attribute
If you prefer a more explicit approach, you can use the Is_A attribute with a type tag (T'Tag). This does the same type-checking but references the type's unique tag identifier directly:
with Ada.Text_IO; use Ada.Text_IO; procedure Check_Peach_With_Is_A is type Peach is tagged null record; My_Peach : Peach'Class := Peach'(null record); begin if My_Peach.Is_A(Peach'Tag) then Put_Line("peach is of type Peach!"); end if; end Check_Peach_With_Is_A;
Why Your is in Attempt Failed
You mentioned trying is in without success—this is almost certainly because you didn’t use the 'Class marker. If you write My_Peach in Peach (without 'Class), Ada only checks the object’s static declared type, not its dynamic type. For polymorphic type checks (the kind instanceof handles), 'Class is mandatory.
Example with Inheritance
To show how this works with a class hierarchy (like Java's parent/child classes):
with Ada.Text_IO; use Ada.Text_IO; procedure Check_Fruits is type Fruit is tagged null record; -- Base class type Peach is new Fruit with null record; -- Derived class type Apple is new Fruit with null record; -- Another derived class procedure Identify_Fruit (F : Fruit'Class) is begin if F in Peach'Class then Put_Line("This is a peach!"); elsif F in Apple'Class then Put_Line("This is an apple!"); else Put_Line("Unknown fruit type"); end if; end Identify_Fruit; My_Peach : Peach; My_Apple : Apple; begin Identify_Fruit(My_Peach); Identify_Fruit(My_Apple); end Check_Fruits;
Running this will correctly identify both fruits, just like instanceof would in Java for a parent class reference pointing to child objects.
内容的提问来源于stack exchange,提问作者D. Ataro

