\hypertarget{qore_classes_class_overview}{}\doxysection{Class Overview}\label{qore_classes_class_overview} Classes define types of Qore \mbox{\hyperlink{container_data_types_object}{objects}}. Classes can define members and methods, which are attributes of the class and functions that operate only on the objects of that class, respectively. Furthermore access to class members and methods can be restricted with the {\ttfamily {\bfseries{private}}} or {\ttfamily {\bfseries{private\+:internal}}} access modifiers, and classes can be \mbox{\hyperlink{qore_classes_inheritance}{subclassed}} to support polymorphism. A class can have any valid identifier name except {\ttfamily \char`\"{}auto\char`\"{}} but may not have the same name as a child namespace of the namespace parent object. \begin{DoxyNote}{Note} Each Qore type has a \char`\"{}pseudo-\/class\char`\"{} associated with it (the default is \mbox{\hyperlink{class_qore_1_1zzz8valuezzz9}{Qore\+::zzz8valuezzz9}}); methods from the data type\textquotesingle{}s \char`\"{}pseudo-\/class\char`\"{} can be run on any value of that type; see \mbox{\hyperlink{class_qore_1_1zzz8valuezzz9}{Qore\+::zzz8valuezzz9}} and {\bfseries{\char`\"{}\+Pseudo Class for Type\char`\"{}}} headings in \mbox{\hyperlink{basic_data_types}{Basic Data Types}} for more information. \end{DoxyNote} \begin{DoxyParagraph}{In-\/\+Line Class Declaration Syntax} {\ttfamily {\bfseries{\mbox{[}\mbox{\hyperlink{qore_modules_mod_public}{public}}\mbox{]} \mbox{[}\mbox{\hyperlink{qore_classes_final_classes}{final}}\mbox{]} class}} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape class\+\_\+identifier}{\ttfamily \mbox{]} \mbox{[}{\bfseries{inherits}} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_inheritance}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_inheritance}{public}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape parent\+\_\+class\+\_\+identifier}{\ttfamily \mbox{[}, ...\mbox{]}\mbox{]} \{}~\newline ~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_members}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_transient}{transient}}}}\mbox{]} }{\itshape member\+\_\+name}{\ttfamily \mbox{[}, ...\mbox{]};\mbox{]}}~\newline ~\newline ~~~~{\ttfamily \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_members}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_members}{public}}}} \{}~\newline ~~~~~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_transient}{transient}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{member\+\_\+type}}}{\ttfamily \mbox{]} }{\itshape member\+\_\+name} {\ttfamily \mbox{[}= }{\itshape \mbox{\hyperlink{expressions}{initialization\+\_\+expression}}}{\ttfamily \mbox{]};\mbox{]}}~\newline ~~~~~~~~{\ttfamily \mbox{[}{\bfseries{static}} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{static\+\_\+member\+\_\+type}}}{\ttfamily \mbox{]} }{\itshape static\+\_\+member\+\_\+name} {\ttfamily \mbox{[}= }{\itshape \mbox{\hyperlink{expressions}{initialization\+\_\+expression}}}{\ttfamily \mbox{]};\mbox{]}}~\newline ~~~~~~~~{\ttfamily \mbox{[}{\bfseries{const}} }{\itshape constant\+\_\+name} {\ttfamily =} {\itshape \mbox{\hyperlink{expressions}{initialization\+\_\+expression}}}{\ttfamily ;\mbox{]}}~\newline ~~~~{\ttfamily \}\mbox{]}}~\newline ~\newline ~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{deprecated}{deprecated}}}}\mbox{]} {\bfseries{constructor}}(\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]}) \mbox{[}\+: }{\itshape parent\+\_\+class\+\_\+name}{\ttfamily (}{\itshape args...}{\ttfamily ), ...\mbox{]} \{}~\newline ~~~~{\ttfamily \}\mbox{]}}~\newline ~~~~{\ttfamily \mbox{[}{\bfseries{copy}}({\ttfamily \mbox{\hyperlink{data_type_declarations_object_type}{object}} }{\itshape arg\+\_\+name}) \{}~\newline ~~~~{\ttfamily \}\mbox{]}}~\newline ~~~~{\ttfamily \mbox{[}{\bfseries{destructor}}() \{}~\newline ~~~~{\ttfamily \}\mbox{]}}~\newline ~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_static_methods}{static}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_final_methods}{final}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{threading_synchronized}{synchronized}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{deprecated}{deprecated}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{return\+\_\+type}}}{\ttfamily \mbox{]}} {\itshape method\+\_\+name}{\ttfamily (\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]}) \{}~\newline ~~~~{\ttfamily \}\mbox{]}}~\newline ~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_abstract}{abstract}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{return\+\_\+type}}}{\ttfamily \mbox{]}} {\itshape method\+\_\+name}{\ttfamily (\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]});\mbox{]}}~\newline ~~~~{\ttfamily ...}~\newline {\ttfamily \}} \end{DoxyParagraph} \begin{DoxyNote}{Note} To define a class interface, define a class with \mbox{\hyperlink{qore_classes_abstract}{abstract methods}}. \end{DoxyNote} When defining a \mbox{\hyperlink{qore_modules_user_modules}{user module}}, class declarations can be preceded by \mbox{\hyperlink{qore_modules_mod_public}{public}}, which means that the class will be available (imported) in the \mbox{\hyperlink{class_qore_1_1_program}{Program}} object importing the module. When a class is declared \mbox{\hyperlink{qore_modules_mod_public}{public}} outside of a \mbox{\hyperlink{qore_modules_user_modules}{user module}}, it means that the class can be inherited in any child \mbox{\hyperlink{class_qore_1_1_program}{Program}} objects created in the same scope. See \mbox{\hyperlink{qore_modules_mod_public}{public}} for more information. Note that classes can also be imported singly by using the \mbox{\hyperlink{class_qore_1_1_program_abf634534cb29157d05aab5ff3ffd6bea}{Program\+::import\+Class()}} method. \begin{DoxyParagraph}{In-\/\+Line Class Declaration Example} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }MyClass inherits MyBaseClass \{} \DoxyCodeLine{ public \{} \DoxyCodeLine{ string pub\_attr = \textcolor{stringliteral}{"{}hello"{}};} \DoxyCodeLine{ const pub\_const = \textcolor{stringliteral}{"{}foo"{}};} \DoxyCodeLine{ static pub\_static\_var = \textcolor{stringliteral}{"{}bar"{}};} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ constructor(string arg) : MyBaseClass(arg + 1) \{} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ softstring myMethod(softint i) \{} \DoxyCodeLine{ \textcolor{keywordflow}{return} i + 2;} \DoxyCodeLine{ \}} \DoxyCodeLine{\}} \end{DoxyCode} \end{DoxyParagraph} \begin{DoxyNote}{Note} No semicolon ({\ttfamily \char`\"{};\char`\"{}}) is required to terminate a class declaration (in fact using a semicolon would raise a parse exception). \end{DoxyNote} \begin{DoxyParagraph}{Out-\/\+Of-\/\+Line Class Declaration Syntax} Alternatively class declarations and method declarations can be defined out of line as follows\+:~\newline {\ttfamily \mbox{[}\mbox{\hyperlink{qore_modules_mod_public}{public}}\mbox{]} {\bfseries{class}} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape class\+\_\+identifier}{\ttfamily \mbox{[}{\bfseries{inherits}} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_inheritance}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_inheritance}{public}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape parent\+\_\+class\+\_\+identifier}{\ttfamily \mbox{[}, ...\mbox{]}\mbox{]};}~\newline ~\newline {\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{deprecated}{deprecated}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape class\+\_\+identifier}{\ttfamily \+::{\bfseries{constructor}}(\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]}) \mbox{[}\+: }{\itshape parent\+\_\+class\+\_\+name}{\ttfamily (}{\itshape args...}{\ttfamily ), ...\mbox{]} \{}~\newline {\ttfamily \}\mbox{]}}~\newline ~\newline {\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_static_methods}{static}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_final_methods}{final}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{threading_synchronized}{synchronized}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{deprecated}{deprecated}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{return\+\_\+type}}}{\ttfamily \mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}{\ttfamily \+::...\mbox{]}}class\+\_\+identifier}{\ttfamily \+::}{\itshape method\+\_\+name}{\ttfamily (\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]}) \{}~\newline {\ttfamily \}\mbox{]}} {\ttfamily \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_abstract}{abstract}}}} \mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{return\+\_\+type}}}{\ttfamily \mbox{]} \mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}{\ttfamily \+::...\mbox{]}}class\+\_\+identifier}{\ttfamily \+::}{\itshape method\+\_\+name}{\ttfamily (\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]});}~\newline As with inline class definitions, when defining a \mbox{\hyperlink{qore_modules_user_modules}{user module}}, class declarations can be preceded by \mbox{\hyperlink{qore_modules_mod_public}{public}}, which means that the class will be available (imported) in the \mbox{\hyperlink{class_qore_1_1_program}{Program}} object importing the module. When a class is declared \mbox{\hyperlink{qore_modules_mod_public}{public}} outside of a \mbox{\hyperlink{qore_modules_user_modules}{user module}}, it means that the class can be inherited in any child \mbox{\hyperlink{class_qore_1_1_program}{Program}} objects created in the same scope. See \mbox{\hyperlink{qore_modules_mod_public}{public}} for more information. Note that classes can also be imported singly by using the \mbox{\hyperlink{class_qore_1_1_program_abf634534cb29157d05aab5ff3ffd6bea}{Program\+::import\+Class()}} method. \end{DoxyParagraph} \begin{DoxyParagraph}{Out-\/\+Of-\/\+Line Class Declaration Example} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }MyNamespace::MyClass inherits MyBaseClass;} \DoxyCodeLine{} \DoxyCodeLine{MyNamespace::MyClass::constructor(string arg = \textcolor{stringliteral}{"{}temp"{}}) : MyBaseClass(arg + \textcolor{stringliteral}{"{}.txt"{}}) \{} \DoxyCodeLine{\}} \DoxyCodeLine{} \DoxyCodeLine{softstring MyNamespace::MyClass::myMethod(softint i) \{} \DoxyCodeLine{ \textcolor{keywordflow}{return} i + 2;} \DoxyCodeLine{\}} \end{DoxyCode} \end{DoxyParagraph} \begin{DoxyNote}{Note} Because method definitions are allowed out-\/of-\/line, this means that builtin classes may be extended with new user methods, however user constructor, destructor, and copy methods cannot be added to builtin classes; to customize the behavior of these methods for builtin classes, subclass the class instead.~\newline ~\newline When parse option \mbox{\hyperlink{parse_directives_allow-bare-refs}{\%allow-\/bare-\/refs}} or \mbox{\hyperlink{parse_directives_new-style}{\%new-\/style}} is enabled, no {\ttfamily \char`\"{}\$\char`\"{}} or {\ttfamily \char`\"{}\$.\char`\"{}} prefixes can be used with variable or method or member names. Class members, class constants, and static class variables can only be declared in an in-\/line class definition (the first example above). If a class has at least one public member declared (or inherits a class with at least one public member declared), then only those members declared as public can be accessed from outside the class, and from within the class only members explicitly declared can be accessed as well (unless the class also defines a member\+Gate() method). In this way typographical errors in member names can be caught (at parse time if types are declared).~\newline ~\newline In a class hierarchy, base class constructor methods can be explicitly specified using a special syntax unique to subclass constructor methods. Please see \mbox{\hyperlink{qore_classes_inheritance}{Class Inheritance}} for more information.~\newline ~\newline It\textquotesingle{}s possible to write purely object-\/oriented scripts/programs in Qore by defining an application class and using the {\ttfamily \char`\"{}-\/x\char`\"{}} or {\ttfamily \char`\"{}-\/-\/exec-\/class\char`\"{}} command-\/line arguments to tell Qore to instantiate the class instead of doing normal top-\/level execution (in fact, the {\ttfamily \char`\"{}-\/-\/exec-\/class\char`\"{}} argument disallows the use of top-\/level statements entirely). For more information, please see \mbox{\hyperlink{command_line_processing}{qore Executable Command-\/\+Line Processing}} and \mbox{\hyperlink{parse_directives}{Parse Directives}}. \end{DoxyNote} \label{qore_classes_final_classes}% \Hypertarget{qore_classes_final_classes}% \begin{DoxyParagraph}{Final Classes} Classes declared {\bfseries{{\ttfamily final}}} cannot be subclassed, and, by extension, no methods of a {\bfseries{{\ttfamily final}}} class can be reimplemented as well.~\newline ~\newline Currently the Qore standard class library (delivered with Qore) has no {\bfseries{{\ttfamily final}}} classes. \end{DoxyParagraph} \hypertarget{qore_classes_class_methods}{}\doxysection{Class Methods}\label{qore_classes_class_methods} \label{qore_classes_public_methods}% \Hypertarget{qore_classes_public_methods}% \begin{DoxyParagraph}{Public Methods} All class methods are public by default, but methods can also be explicitly declared with the {\ttfamily {\bfseries{public}}} access modifier as well. Public methods have no class protection and can be called from any code context. \end{DoxyParagraph} \label{qore_classes_private_methods}% \Hypertarget{qore_classes_private_methods}% \begin{DoxyParagraph}{Private Methods} Methods declared with the {\ttfamily {\bfseries{private}}} access modifier can only be called by other member methods of the same class or in the same class hierarchy. Any attempt to call these methods from outside the class hierarchy will result in a run-\/time exception. This access modifier, when used without any modifiers, is equivalent to {\ttfamily {\bfseries{private\+:hierarchy}}} and is functionally identical to C++\textquotesingle{}s {\itshape protected} access modifier.~\newline ~\newline Methods declared as {\ttfamily {\bfseries{private\+:internal}}} are not available outside the class, even in classes in the same class hierarchy, providing strong encapsulation of the declared method. This can be used to ensure that the declared method can be changed in later versions of the class without affecting API compatibility.~\newline ~\newline Methods declared as {\ttfamily {\bfseries{private\+:hierarchy}}} are equivalent to those declared {\ttfamily {\bfseries{private}}} and are only private from outside the class hierarchy. \end{DoxyParagraph} \label{qore_classes_synchronized_methods}% \Hypertarget{qore_classes_synchronized_methods}% \begin{DoxyParagraph}{Synchronized Methods} Methods declared with the {\ttfamily {\bfseries{synchronized}}} keyword will only run in one thread at a time.~\newline ~\newline {\ttfamily {\bfseries{synchronized}}} normal class methods share a reentrant lock associated with the object, while {\ttfamily {\bfseries{synchronized}}} static class methods share a reentrant lock associated with the class itself.~\newline ~\newline For more information, see the \mbox{\hyperlink{threading_synchronized}{synchronized keyword}}. \end{DoxyParagraph} \label{qore_classes_static_methods}% \Hypertarget{qore_classes_static_methods}% \begin{DoxyParagraph}{Static Methods} Methods declared with the {\ttfamily {\bfseries{static}}} keyword are like regular functions that are attached to the class. These methods are not associated with a particular object\textquotesingle{}s state and therefore are not allowed to refer to object members or call non-\/static methods. Also, no reference to the special {\ttfamily self} variable is allowed within static methods.~\newline ~\newline Static methods may be declared {\ttfamily {\bfseries{private}}}, {\ttfamily {\bfseries{private\+:internal}}}, or {\ttfamily {\bfseries{public}}} or {\ttfamily {\bfseries{synchronized}}} like non-\/static methods; static methods can also access private members of a class (through an object of the class for non-\/static members). Static methods may not be also \mbox{\hyperlink{qore_classes_abstract}{abstract}}.~\newline ~\newline Static method calls take a special syntax as documented in \mbox{\hyperlink{expressions_static_method_calls}{Static Method Calls}} .~\newline \label{qore_classes_abstract}% \Hypertarget{qore_classes_abstract}% \end{DoxyParagraph} \begin{DoxyParagraph}{Abstract Methods} Methods declared with the {\ttfamily {\bfseries{abstract}}} keyword define methods interfaces that must be defined in child classes for the class to be instantiated. Methods defining the declared interfaces in child classes must define exactly the same parameters in order for the abstract method to match, but the return type of the concrete method in the child class has to simply be compatible with the return type of the abstract method in the parent class.~\newline ~\newline Classes with undefined abstract methods cannot be instantiated. Abstract methods cannot have a method body; an abstract method\textquotesingle{}s declaration must be terminated with a semicolon ({\ttfamily \char`\"{};\char`\"{}}). Furthermore, abstract methods cannot be also \mbox{\hyperlink{qore_classes_static_methods}{static}}.~\newline ~\newline The {\ttfamily {\bfseries{abstract}}} keyword can only be used in abstract method declaration; the use of this keyword with a method declaration with a method body will cause a parse exception to be thrown. \end{DoxyParagraph} \label{qore_classes_class_special_methods}% \Hypertarget{qore_classes_class_special_methods}% \begin{DoxyParagraph}{Constructors, Destructors, and Other Special Methods} All class methods are optional, but some methods have a special meaning.~\newline ~\newline {\bfseries{Special Methods}} \tabulinesep=1mm \begin{longtabu}spread 0pt [c]{*{2}{|X[-1]}|} \hline {\bfseries{Name}} &{\bfseries{Description}} \\\cline{1-2} {\ttfamily constructor(}{\itshape \mbox{[}params...\mbox{]}}{\ttfamily ) \{\}} &Called when objects are created when instantiated by a variable declaration with a class type and constructor arguments or explicitly with the new operator. User code may not explicitly call {\ttfamily constructor()} methods directly. In a class tree, {\ttfamily constructor()} methods are called for base classes first in left-\/to-\/right, depth-\/first declaration order.~\newline ~\newline {\ttfamily constructor()} methods may be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and also private constructors may be defined. Constructors declared {\ttfamily {\bfseries{private}}} can only be called from within the class hierarchy, and those declared {\ttfamily {\bfseries{private\+:internal}}} can only be called within the class itself. \\\cline{1-2} {\ttfamily copy() \{\}} &When a user explicitly calls a copy method, Qore will generate a new object with references to the same members as the source object. Then, if there are any base classes, base class {\ttfamily copy()} methods are called in the same order as the {\ttfamily constructor()} methods. If a {\ttfamily copy()} method is defined, it will be run in the new object with a reference to the old object passed as the first argument. Any other arguments passed to the {\ttfamily copy()} method are ignored.~\newline ~\newline {\ttfamily copy()} methods cannot be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and cannot be private. \\\cline{1-2} {\ttfamily destructor() \{\}} &Called when objects are implicitly collected (see \mbox{\hyperlink{container_data_types_garbage_collection}{Garbage Collection and Resource Management}}) or are explicitly deleted. User code may not explicitly call {\ttfamily destructor()} methods. In a class tree, {\ttfamily destructor()} methods are called for base classes in the opposite order in which the constructors are called.~\newline ~\newline {\ttfamily destructor()} methods cannot be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and cannot be private. \\\cline{1-2} \mbox{\hyperlink{data_type_declarations_any_type}{any}} {\ttfamily \mbox{\hyperlink{qore_classes_memberGate_methods}{member\+Gate}}(}\mbox{\hyperlink{data_type_declarations_string_type}{string}} {\ttfamily \$}{\itshape member\+\_\+param\+\_\+name}{\ttfamily ) \{\}} &If this method is implemented in the class, it is called when read access is attempted to private member or members that do not exist in the current object; the return value of this method is returned as the value of the member.~\newline ~\newline {\ttfamily member\+Gate()} methods cannot be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and are not inherited by subclasses. \\\cline{1-2} \mbox{\hyperlink{data_type_declarations_any_type}{any}} {\ttfamily \mbox{\hyperlink{qore_classes_methodGate_methods}{method\+Gate}}(}\mbox{\hyperlink{data_type_declarations_string_type}{string}} {\ttfamily \$}{\itshape method\+\_\+param\+\_\+name}{\ttfamily , ...) \{\}} &If this method is implemented in the class, it is called when methods are called on the object that do not exist in the current object and the return value of this method is returned as the value of the method call.~\newline ~\newline {\ttfamily method\+Gate()} methods cannot be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and are not inherited by subclasses. \\\cline{1-2} {\ttfamily \mbox{\hyperlink{qore_classes_memberNotification_methods}{member\+Notification}}(}\mbox{\hyperlink{data_type_declarations_string_type}{string}} {\ttfamily \$}{\itshape member\+\_\+param\+\_\+name}{\ttfamily ) \{\}} &If this method is implemented in the class, it is called when an object member is updated outside the class with the member name as the argument. Note that this method is called after the member has been updated and without locking; the call is not atomic respective to other threads that also may update the same member simultaneously.~\newline ~\newline {\ttfamily member\+Notification()} methods cannot be \mbox{\hyperlink{overloading_overloaded_methods}{overloaded}} and are not inherited by subclasses. \\\cline{1-2} \end{longtabu} \end{DoxyParagraph} \label{qore_classes_final_methods}% \Hypertarget{qore_classes_final_methods}% \begin{DoxyParagraph}{Final Methods} Methods declared {\bfseries{{\ttfamily final}}} cannot be reimplemented in a subclass. Methods can be declared {\bfseries{{\ttfamily final}}} to prevent a subclass from altering the behavior of a method that is critical to the class\textquotesingle{}s functionality.~\newline ~\newline None of the following special methods can be declared {\bfseries{{\ttfamily final}}}\+: \begin{DoxyItemize} \item constructor()\+: declare the class \mbox{\hyperlink{qore_classes_final_classes}{final}} instead \item destructor()\+: declare the class \mbox{\hyperlink{qore_classes_final_classes}{final}} instead \item copy()\+: declare the class \mbox{\hyperlink{qore_classes_final_classes}{final}} instead \item \mbox{\hyperlink{qore_classes_memberGate_methods}{member\+Gate()}}\+: these methods are not inherited so they may not be declared {\bfseries{{\ttfamily final}}} \item \mbox{\hyperlink{qore_classes_memberNotification_methods}{member\+Notification()}}\+: these methods are not inherited so they may not be declared {\bfseries{{\ttfamily final}}} \item method\+Gate()\+: these methods are not inherited so they may not be declared {\bfseries{{\ttfamily final}}} \end{DoxyItemize} \end{DoxyParagraph} Currently the Qore standard class library has no {\bfseries{{\ttfamily final}}} methods. \label{qore_classes_class_constants}% \Hypertarget{qore_classes_class_constants}% \begin{DoxyParagraph}{Class Constants} Class constants, like non-\/class constants, allow programmers to refer to values with Qore identifiers rather than using the value or the expression that generates the value.~\newline ~\newline See \mbox{\hyperlink{qore_classes_class_overview}{Class Overview}} for a description of the syntax required to declare a class constant.~\newline ~\newline Like other attributes of classes, class constants may be declared {\ttfamily {\bfseries{private}}}, {\ttfamily {\bfseries{private\+:internal}}}, or {\ttfamily {\bfseries{public}}}. The following are examples of class constant definitions\+:~\newline \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }Test \{} \DoxyCodeLine{ public \{} \DoxyCodeLine{ const Version = \textcolor{stringliteral}{"{}1.0"{}};} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ private \{} \DoxyCodeLine{ const Limit = 100;} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ private:internal \{} \DoxyCodeLine{ const Other = \textcolor{stringliteral}{"{}string"{}};} \DoxyCodeLine{ \}} \DoxyCodeLine{\}} \end{DoxyCode} \end{DoxyParagraph} \begin{DoxyNote}{Note} Class constants cannot have the same names as \mbox{\hyperlink{qore_classes_static_class_variables}{static class variables}}. \end{DoxyNote} \label{qore_classes_static_class_variables}% \Hypertarget{qore_classes_static_class_variables}% \begin{DoxyParagraph}{Static Class Variables} Static class variables are like global variables that belong to a class. They are not associated with any particular object.~\newline ~\newline See \mbox{\hyperlink{qore_classes_class_overview}{Class Overview}} for a description of the syntax required to declare a static class variable.~\newline ~\newline Like other attributes of classes, static class variables may be declared {\ttfamily {\bfseries{private}}}, {\ttfamily {\bfseries{private\+:internal}}}, or {\ttfamily {\bfseries{public}}}. The following are examples of static class variable definitions\+:~\newline \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }Test \{} \DoxyCodeLine{ public \{} \DoxyCodeLine{ static string lastFile = \textcolor{stringliteral}{"{}none"{}};} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ private \{} \DoxyCodeLine{ static int numProcessed = 0;} \DoxyCodeLine{ \}} \DoxyCodeLine{} \DoxyCodeLine{ private:internal \{} \DoxyCodeLine{ static string other = \textcolor{stringliteral}{"{}string"{}};} \DoxyCodeLine{ \}} \DoxyCodeLine{\}} \end{DoxyCode} \end{DoxyParagraph} \begin{DoxyNote}{Note} Static class variables cannot have the same name as class constants. \end{DoxyNote} \hypertarget{qore_classes_class_members}{}\doxysection{Class Members}\label{qore_classes_class_members} \hypertarget{qore_classes_public_members}{}\doxysubsection{Public Member Declarations}\label{qore_classes_public_members} If a class has at least one public member declared (or inherits a class with at least one public member declared), then only those members declared as public can be accessed from outside the class, and from within the class only members explicitly declared can be accessed as well (unless the class also defines a \mbox{\hyperlink{qore_classes_memberGate_methods}{member\+Gate() method}}). In this way typographical errors in member names can be caught (at parse time if types are declared).\hypertarget{qore_classes_private_members}{}\doxysubsection{Private Members}\label{qore_classes_private_members} Members declared {\bfseries{{\ttfamily private}}} can only be accessed within the class hierarchy; trying to access private members form outside the class hierarchy will result in either a parse or runtime exception, depending on when the illegal access is caught. This access modifier, when used without any modifiers, is equivalent to {\ttfamily {\bfseries{private\+:hierarchy}}} and is functionally identical to C++\textquotesingle{}s {\itshape protected} access modifier.~\newline ~\newline Members declared as {\ttfamily {\bfseries{private\+:internal}}} are not available outside the class, even in classes in the same class hierarchy, providing strong encapsulation of the declared member. This can be used to ensure that the declared member can be changed in later versions of the class without affecting API compatibility.~\newline ~\newline Members declared as {\ttfamily {\bfseries{private\+:hierarchy}}} are equivalent to those declared {\ttfamily {\bfseries{private}}} and are only private from outside the class hierarchy.\hypertarget{qore_classes_transient}{}\doxysubsection{Transient Members}\label{qore_classes_transient} Members declared with the {\bfseries{{\ttfamily transient}}} keyword will not be processed with \mbox{\hyperlink{class_qore_1_1_serializable}{object serialization}} and will get their default value (if any) when deserialized.\hypertarget{qore_classes_referencing_members}{}\doxysubsection{Class Member References}\label{qore_classes_referencing_members} When defining a class when using the old style syntax, members of instantiated objects are referred to with a special syntax as follows\+:~\newline {\ttfamily \$.}{\itshape member\+\_\+name}~\newline ~\newline Furthermore, the automatic variable {\ttfamily self} is instantiated in every non-\/static method, representing the current object (similar to {\ttfamily this} in C++ or Java). Therefore if you need to access hash members which are not valid Qore identifiers, then enclose the member name in double quotes after the dot operator as follows\+:~\newline \begin{DoxyCode}{0} \DoxyCodeLine{self.\textcolor{stringliteral}{"{}\&member-\/name"{}}} \end{DoxyCode} \hypertarget{qore_classes_memberGate_methods}{}\doxysubsection{member\+Gate() Method}\label{qore_classes_memberGate_methods} If the class implements a {\ttfamily member\+Gate()} method, then whenever a non-\/existent member of the class is accessed (read), this method will be called with the name of the member as the sole argument, so that the class can create the member (or react in some other way) on demand. This method is also called when methods of the same class try to access (read) non-\/existent methods, but is not called from within the {\ttfamily member\+Gate()} method itself. \begin{DoxyNote}{Note} {\ttfamily member\+Gate()} methods are not inherited; they must be explicitly implemented in each class \end{DoxyNote} \hypertarget{qore_classes_memberNotification_methods}{}\doxysubsection{member\+Notification() Methods}\label{qore_classes_memberNotification_methods} To monitor writes to the object, the class can implement a {\ttfamily member\+Notification()} method, which is called whenever an object member is modified from outside class member code. In this case, the {\ttfamily member\+Notification()} method is called with the name of the member that was updated so that an object can automatically react to changes to its members (writes to members) from outside the class. This method is not called when members are updated from within class member code. \begin{DoxyNote}{Note} {\ttfamily member\+Notification()} methods are not inherited; they must be explicitly implemented in each class \end{DoxyNote} \hypertarget{qore_classes_member_initialization}{}\doxysubsection{Member Initialization}\label{qore_classes_member_initialization} Members that have intialization expressions in the class definition are initialized before the constructor is executed (but after any base class constructors have run). An exception raised in a member initialization expression will cause the constructor to fail and for the object to be deleted immediately. \begin{DoxyNote}{Note} The automatic {\ttfamily argv} local variable is instantiated as usual in all class methods where there are more arguments than variables declared in the method declaration.~\newline ~\newline \end{DoxyNote} \hypertarget{qore_classes_object_method_calls}{}\doxysection{Object Method Calls}\label{qore_classes_object_method_calls} \begin{DoxyParagraph}{In-\/\+Class Method Call Syntax} Within a class method definition, calls to methods in the same class hierarchy (of the current class or a base class) can be made as follows\+:~\newline {\ttfamily \mbox{[}\mbox{[}}{\itshape \mbox{\hyperlink{qore_namespaces_namespace_paths}{namespace\+\_\+path}}}{\ttfamily \+::...\mbox{]}}{\itshape parent\+\_\+class\+\_\+name}{\ttfamily \+::\mbox{]}\$.}{\itshape method\+\_\+name}{\ttfamily (\mbox{[}}{\itshape args}{\ttfamily , ...\mbox{]})} \end{DoxyParagraph} \begin{DoxyParagraph}{In-\/\+Class Method Call Example} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{comment}{\# to call a specific method in a base class}} \DoxyCodeLine{Thread::Mutex::lock();} \DoxyCodeLine{\textcolor{comment}{\# to call lock() in the current (or lower base) class}} \DoxyCodeLine{lock();} \end{DoxyCode} \end{DoxyParagraph} \begin{DoxyParagraph}{In-\/\+Class Method Calls with allow-\/bare-\/refs} When the \mbox{\hyperlink{parse_directives_allow-bare-refs}{\%allow-\/bare-\/refs}} or \mbox{\hyperlink{parse_directives_new-style}{\%new-\/style}} parse directive is set, then object methods are called without the {\ttfamily \char`\"{}\$.\char`\"{}} prefix as in the following example\+:~\newline \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{comment}{\# to call a specific method in a base class}} \DoxyCodeLine{Thread::Mutex::lock();} \DoxyCodeLine{\textcolor{comment}{\# to call lock() in the current (or lower base) class}} \DoxyCodeLine{lock();} \end{DoxyCode} ~\newline Calls to object methods can be made outside the class by using the above syntax as well. If the object\textquotesingle{}s class is not known at parse time, then the call is resolved at run-\/time, and if a call is attempted to a private function outside the defining class, then a run-\/time {\ttfamily METHOD-\/\+IS-\/\+PRIVATE} (if the method is private) or {\ttfamily BASE-\/\+CLASS-\/\+IS-\/\+PRIVATE} (if the method resolves to a privately-\/inherited base class) exception is raised. \end{DoxyParagraph} \label{qore_classes_methodGate_methods}% \Hypertarget{qore_classes_methodGate_methods}% \begin{DoxyParagraph}{method\+Gate() methods} If the class implements a {\ttfamily method\+Gate()} method, then whenever a non-\/existent method of the class is called, the method\+Gate() method will be called with the name of the member as the first argument (prepended to the other arguments to the non-\/existant method), so that the class simulate or redirect the method call. This method is also called when methods of the same class try to call non-\/existent methods, but is not called from within the {\ttfamily method\+Gate()} method itself. \end{DoxyParagraph} \begin{DoxyNote}{Note} {\ttfamily method\+Gate()} methods are not inherited; they must be explicitly implemented in each class \end{DoxyNote} \hypertarget{qore_classes_inheritance}{}\doxysection{Class Inheritance}\label{qore_classes_inheritance} Class inheritance is a powerful concept for easily extending and reusing object-\/oriented code, but is also subject to some limitations. This section explains how class inheritance works in Qore. Classes inherit the methods of a parent class by using the {\ttfamily {\bfseries{inherits}}} keyword as specified above. Multiple inheritance is supported; a single Qore class can inherit one or more classes. When a class is inherited by another class, it is called a base class or parent class. \mbox{\hyperlink{qore_classes_private_inheritance}{Private inheritance}} is specified by including the {\ttfamily {\bfseries{private}}} access modifier before the inherited class\textquotesingle{}s name. When a class is privately inherited, it means that the inherited class\textquotesingle{}s public declarations (members, constants, methods, etc) are treated as private in the context of accesses outside the class hierarchy. To limit access of a base class to only the directly inheriting class, use the {\ttfamily {\bfseries{private\+:internal}}} access modifier. Classes inherited with {\ttfamily {\bfseries{private\+:internal}}} are not accessible to the hierarchy in general but rather only to the directly inheriting class. Inheritance is {\ttfamily {\bfseries{public}}} \mbox{\hyperlink{qore_classes_public_inheritance}{by default}}, to inherit a class privately, such that the inherted class is accessible within all child classes in the hierarchy, use the {\ttfamily {\bfseries{private}}} access modifier before the class name or class path to inherit as follows\+: \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }ChildClass inherits private ParentClass \{} \DoxyCodeLine{\}} \end{DoxyCode} To inherit a class where the inherited class is only available to the inheriting class but not to child classes, use the {\ttfamily {\bfseries{private\+:internal}}} access modifier before the class name or class path as follows\+: \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }ChildClass inherits private:internal ParentClass \{} \DoxyCodeLine{\}} \end{DoxyCode} It is not legal to directly inherit the same class directly more than once; that is; it is not legal to list the same class more than once after the {\ttfamily {\bfseries{inherits}}} keyword. However, it is possible that a base class could appear more than once in the inheritance tree if that class is inherited separately by two or more classes in the tree. In this case, the base class will actually only be inherited once in the subclass, even though it appears in the inheritance tree more than once. This must be taken into consideration when designing class hierarchies, particularly if base class constructor parameters for that class are explicitly provided in a different way by the inheriting classes. \begin{DoxyNote}{Note} Class members only exist once for each object; therefore if classes in an inheritance tree have different uses for members with the same name, then a class hierarchy built of such classes will probably not function properly. \end{DoxyNote} Subclasses can give explicit arguments to their base class constructors using a special syntax (only available to subclass constructors) similar to the C++ syntax for the same purpose as follows\+:~\newline ~~~~{\ttfamily \mbox{[}\mbox{[}{\bfseries{\mbox{\hyperlink{qore_classes_private_methods}{private\mbox{[}\+:internal$\vert$hierarchy\mbox{]}}}}}$\vert${\bfseries{\mbox{\hyperlink{qore_classes_public_methods}{public}}}}\mbox{]} \mbox{[}{\bfseries{\mbox{\hyperlink{deprecated}{deprecated}}}}\mbox{]} {\bfseries{constructor}}(\mbox{[}}{\itshape \mbox{\hyperlink{data_type_declarations}{\mbox{[}param\+\_\+type\mbox{]}}}} {\ttfamily \$}{\itshape param\+\_\+name} {\ttfamily \mbox{[}=} {\itshape \mbox{\hyperlink{expressions}{default\+\_\+initialization\+\_\+expression}}}{\ttfamily \mbox{]}, ...\mbox{]}) \mbox{[}\+: }{\itshape parent\+\_\+class\+\_\+name}{\ttfamily (}{\itshape args...}{\ttfamily ), ...\mbox{]} \{}~\newline ~~~~{\ttfamily \}\mbox{]}} Here is a concrete example of giving arguments to an inherited base class\+: \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }XmlRpcClient inherits \mbox{\hyperlink{namespace_qore}{Qore}}::HTTPClient \{} \DoxyCodeLine{ \textcolor{comment}{\# calls the base class HTTPClient constructor, overrides the "{}protocols"{} key to "{}xmlrpc"{}}} \DoxyCodeLine{ constructor(hash opts = \mbox{\hyperlink{group__type__conversion__functions_ga0231dbb472dd230310af7c7c34f56e92}{hash}}()) : Qore::HTTPClient(opts + ( \textcolor{stringliteral}{"{}protocols"{}} : \textcolor{stringliteral}{"{}xmlrpc"{}} )) \{} \DoxyCodeLine{ \}} \DoxyCodeLine{\}} \end{DoxyCode} Because base class constructors are executed before subclass constructors, the only local variables in the constructor that can be referenced are those declared in the subclass constructor declaration (if any). What this means is that if you declare local variables in the expressions giving base class arguments, these local variables are not accessible from the constructor body. \begin{DoxyNote}{Note} Base classes that give explicit arguments to their base class constructors can be overridden by subclasses by simply listing the base class in the base class constructor list and providing new arguments. \end{DoxyNote} \hypertarget{qore_classes_private_inheritance}{}\doxysubsection{Private Inheritance}\label{qore_classes_private_inheritance} Classes inherited using the {\bfseries{{\ttfamily private}}} access modifier encapsulate the functionality (members, constants, methods, etc) of the parent class privately in the class hierarchy; that is, any access to the privately-\/inherited parent class\textquotesingle{}s functionality from outside the class hierarchy will result in either a parse-\/time or runtime exception, depending on when the error is caught. When inheritance is declared {\ttfamily {\bfseries{private}}}, the inherted class is accessible in all child classes in the hierarchy. Classes inherited using the {\ttfamily {\bfseries{private\+:internal}}} access modifier limit access to the inherited class to the child class; the inherited class in this case is not available in the rest of the class hierarchy but is limited to the directly inheriting child class.\hypertarget{qore_classes_public_inheritance}{}\doxysubsection{Public Inheritance}\label{qore_classes_public_inheritance} Classes are inherited publically by default; public inheritance means that the parent class\textquotesingle{}s functionality (members, constants, methods, etc) have the same visibility in the child class as they do in the parent class. For example, a public method in the parent class will also be public in the child class if the parent class is inherited publically. Respectively, private methods of publically-\/inherited parent classes will still be private in child classes.