Jump to content

Тип самоанализ

(Перенаправлено из самоанализа кода )

В вычислительной технике интроспекция типов — это способность программы исследовать тип . или свойства объекта во время выполнения . Некоторые языки программирования обладают такой возможностью.

Интроспекцию не следует путать с отражением , которое идет еще дальше и представляет собой способность программы манипулировать метаданными, свойствами и функциями объекта во время выполнения. Некоторые языки программирования также обладают такой возможностью (например, Ява , Питон , Юля , и Идти ).

в Objective-C Например, и общий Object, и NSObject (в Cocoa / OpenStep ) предоставляют метод isMemberOfClass: который возвращает true, если аргумент метода является экземпляром указанного класса. Метод isKindOfClass: аналогично возвращает true, если аргумент наследуется от указанного класса.

Например, скажем, у нас есть Apple и Orange класс, наследующий от Fruit.

Теперь, в eat метод, который мы можем написать

- (void)eat:(id)sth {
    if ([sth isKindOfClass:[Fruit class]]) {
        // we're actually eating a Fruit, so continue
        if ([sth isMemberOfClass:[Apple class]]) {
            eatApple(sth);
        } else if ([sth isMemberOfClass:[Orange class]]) {
            eatOrange(sth);
        } else {
            error();
        }
    } else {
        error();
    }
}

Теперь, когда eat вызывается с универсальным объектом ( id), функция будет вести себя правильно в зависимости от типа универсального объекта.

C++ поддерживает интроспекцию типов с помощью информации о типе времени выполнения (RTTI) ключевых слов typeid и Dynamic_cast . dynamic_cast Выражение можно использовать для определения того, принадлежит ли конкретный объект к определенному производному классу. Например:

Person* p = dynamic_cast<Person *>(obj);
if (p != nullptr) {
  p->walk();
}

The typeid оператор извлекает std::type_info объект, описывающий наиболее производный тип объекта:

if (typeid(Person) == typeid(*obj)) {
  serialize_person( obj );
}

Объектный Паскаль

[ редактировать ]

Интроспекция типов была частью Object Pascal с момента выхода оригинальной версии Delphi, которая активно использует RTTI для визуального проектирования форм. В Object Pascal все классы происходят от базового класса TObject, который реализует базовую функциональность RTTI. На имя каждого класса можно ссылаться в коде для целей RTTI; идентификатор имени класса реализован как указатель на метаданные класса, которые можно объявить и использовать как переменную типа TClass. Язык включает оператор is , определяющий, является ли объект заданным классом или происходит от него, оператор as , обеспечивающий приведение типов с проверкой типа, и несколько методов TObject. Более глубокий самоанализ (перечисление полей и методов) традиционно поддерживается только для объектов, объявленных в состоянии $M+ (прагма), обычно TPersistent, и только для символов, определенных в опубликованном разделе. В Delphi 2010 это значение увеличено почти для всех символов.

procedure Form1.MyButtonOnClick(Sender: TObject);
var
   aButton: TButton;
   SenderClass: TClass;
begin
   SenderClass := Sender.ClassType; //returns Sender's class pointer
   if sender is TButton then
   begin
      aButton := sender as TButton;
      EditBox.Text := aButton.Caption; //Property that the button has but generic objects don't
   end
   else begin
      EditBox.Text := Sender.ClassName; //returns the name of Sender's class as a string
   end;
end;

Простейшим примером интроспекции типов в Java является instanceof[1] оператор. instanceof Оператор определяет, принадлежит ли конкретный объект определенному классу (или подклассу этого класса, или классу, реализующему этот интерфейс). Например:

if (obj instanceof Person) {
    Person p = (Person)obj;
    p.walk();
}

The java.lang.Class[2] класс является основой более продвинутого самоанализа.

Например, если желательно определить фактический класс объекта (а не то, является ли он членом определенного класса ), Object.getClass() и Class.getName() можно использовать:

System.out.println(obj.getClass().getName());

В PHP самоанализ можно выполнить с помощью instanceof оператор. Например:

if ($obj instanceof Person) {
    // Do whatever you want
}

Самоанализа можно достичь с помощью ref и isa функции в Perl .

Мы можем проанализировать следующие классы и соответствующие им экземпляры:

package Animal;
sub new {
    my $class = shift;
    return bless {}, $class;
}

package Dog;
use base 'Animal';

package main;
my $animal = Animal->new();
my $dog = Dog->new();

с использованием:

print "This is an Animal.\n" if ref $animal eq 'Animal';
print "Dog is an Animal.\n" if $dog->isa('Animal');

Мета-объектный протокол

[ редактировать ]

Гораздо более мощный самоанализ в Perl может быть достигнут с использованием Moose. объектной системы [3] и Class::MOP метаобъектный протокол; [4] например, вы можете проверить, выполняет ли объект роль X данный :

if ($object->meta->does_role("X")) {
    # do something ...
}

Вот как вы можете перечислить полные имена всех методов, которые можно вызвать для объекта, вместе с классами, в которых они были определены:

for my $method ($object->meta->get_all_methods) {
    print $method->fully_qualified_name, "\n";
}

Самый распространенный метод самоанализа в Python — использование dir функция для детализации атрибутов объекта. Например:

class Foo:
    def __init__(self, val):
        self.x = val

    def bar(self):
        return self.x
>>> dir(Foo(5))
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', '__weakref__', 'bar', 'x']

Также встроенные функции type и isinstance может использоваться для определения того, что представляет собой объект , пока hasattr объект может определить, что делает . Например:

>>> a = Foo(10)
>>> b = Bar(11)
>>> type(a)
<type 'Foo'>
>>> isinstance(a, Foo)
True
>>> isinstance(a, type(a))
True
>>> isinstance(a, type(b))
False
>>> hasattr(a, 'bar')
True

Интроспекция типов — основная особенность Ruby . В Ruby класс Object (предок каждого класса) предоставляет Object#instance_of? и Object#kind_of? методы для проверки класса экземпляра. Последний возвращает true, когда конкретный экземпляр, которому было отправлено сообщение, является экземпляром потомка рассматриваемого класса. Например, рассмотрим следующий пример кода (вы можете сразу попробовать это с помощью Interactive Ruby Shell ):

$ irb
irb(main):001:0> A=Class.new
=> A
irb(main):002:0> B=Class.new A
=> B
irb(main):003:0> a=A.new
=> #<A:0x2e44b78>
irb(main):004:0> b=B.new
=> #<B:0x2e431b0>
irb(main):005:0> a.instance_of? A
=> true
irb(main):006:0> b.instance_of? A
=> false
irb(main):007:0> b.kind_of? A
=> true

В приведенном выше примере Class class используется как любой другой класс в Ruby. Создаются два класса, A и B, первый является суперклассом второго, тогда проверяется один экземпляр каждого класса. Последнее выражение дает истинное значение, поскольку A является суперклассом класса b.

Кроме того, вы можете напрямую запросить класс любого объекта и «сравнить» их (приведенный ниже код предполагает выполнение приведенного выше кода):

irb(main):008:0> A.instance_of? Class
=> true
irb(main):009:0> a.class
=> A
irb(main):010:0> a.class.class
=> Class
irb(main):011:0> A > B
=> true
irb(main):012:0> B <= A
=> true

В ActionScript (as3) функция flash.utils.getQualifiedClassName может использоваться для получения имени класса/типа произвольного объекта.

// all classes used in as3 must be imported explicitly
import flash.utils.getQualifiedClassName;
import flash.display.Sprite;
// trace is like System.out.println in Java or echo in PHP
trace(flash.utils.getQualifiedClassName("I'm a String")); // "String"
trace(flash.utils.getQualifiedClassName(1)); // "int", see dynamic casting for why not Number
trace(flash.utils.getQualifiedClassName(new flash.display.Sprite())); // "flash.display.Sprite"

Альтернативно, оператор is может использоваться для определения того, принадлежит ли объект к определенному типу:

// trace is like System.out.println in Java or echo in PHP
trace("I'm a String" is String); // true
trace(1 is String); // false
trace("I'm a String" is Number); // false
trace(1 is Number); // true

можно использовать для проверки родителей- наследников классов Эту вторую функцию также :

import flash.display.DisplayObject;
import flash.display.Sprite; // extends DisplayObject

trace(new flash.display.Sprite() is flash.display.Sprite); // true
trace(new flash.display.Sprite() is flash.display.DisplayObject); // true, because Sprite extends DisplayObject
trace(new flash.display.Sprite() is String); // false

Метатипический самоанализ

[ редактировать ]

Как и Perl, ActionScript может пойти дальше, чем просто получить имя класса, но все метаданные, функции и другие элементы, составляющие объект, используют flash.utils.describeType функция; это используется при реализации отражения в ActionScript.

import flash.utils.describeType;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.display.Sprite;

var className:String = getQualifiedClassName(new flash.display.Sprite()); // "flash.display.Sprite"
var classRef:Class = getDefinitionByName(className); // Class reference to flash.display{{Not a typo|.}}Sprite
// eg. 'new classRef()' same as 'new  flash.display.Sprite()'
trace(describeType(classRef)); // return XML object describing type
// same as : trace(describeType(flash.display.Sprite));

См. также

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 108b66516af39078f7b9827ac63cf4e3__1717391040
URL1:https://arc.ask3.ru/arc/aa/10/e3/108b66516af39078f7b9827ac63cf4e3.html
Заголовок, (Title) документа по адресу, URL1:
Type introspection - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)