I understand objects are just chunks of data, where the first member variable starts at the exact same location as the object. For example, an object whose pointer points to location 0x0100, will also have the first member variable located at 0x0100.
But how do interfaces in a language like Java, which have no implementation, work? These are purely abstract types.
As in, how does a CPU or compiler know to interpret Object A as Interface X, or Object B as Interface X and Y depending on the context? Is this something done at the compiler level, that has no bearing on the lower level interpretations?
You need to understand that in languages like Java & C#, the first member of an instance is a pointer to a class-shared object; this object participates in identifying the actual class that was instantiated, in checking down casts, in determining the overrides to call for virtual method invocations, and in determining the implementation to use for interface method invocations.
But how do interfaces in a language like Java, which have no implementation, work? These are purely abstract types.
Sure interfaces themselves are "abstract", but the interface methods are always invoked on instances of concrete classes (that implement the interfaces), so that's where implementation comes in.
The language treats interfaces, similar to classes (both abstract and concrete), assigning their methods to indexes, and using those method indexes in lookup (at the class-shared object of the instance) to find the actual implementation to invoke.
So, key is that the interface methods are given positions in the array of method references within the class-shared object of each instantiable type (that implements the interface), such that each class could have a different implementation of an interface method.
Let be the interface
interface A {
void hello();
void hello2();
}
We can immediately define the function with the interface as a parameter
void function example (i A) {
i.hello();
i.hello2();
}
What exactly will be compiled here?
Interface function calls.
And how is this possible?
It is possible because an interface type variable contains as many pointers to functions as there are functions defined within the interface.
Interface in short is a structure that contains pointer variables to functions.
Now any class that implements the interface can be assigned to it. With this allocation, pointer variables to functions (of the interface) are "filled" with the addresses of the functions located in the vmtable (of the class).
This means that an interface variable always sees the functions defined in it and only them (unless casted to the class)
----------------------------------
So for example if a class implements the interface.
class B implements A {
public int justAField;
#Override
public void hello() {
System.out.println("Hi.");
}
#Override
public void hello2() {
System.out.println("Hi2.");
public void anotherMethod() {
System.out.println("Another one.");
}
}
We can have
example(new B())
The calls i.hello(); i.hello2(); trigger the corresponding functions of the class
Related
I am trying to understand if there could be any issues with Predicate defined at class level in multithreaded application. ? We have defined such predicates in our services and using them up different methods of same class. Currently we have not seen any issue but I am curious to understand our class level Predicate object is going to function. will there be any inconsistency in the behaviour?
eg:
class SomeClass{
Predicate<String> check = (value) -> value.contains("SomeString");
// remaning impl. of the class.
}
The predicate in your example is categorically thread-safe. It is calling a method on an intrinsicly thread-safe (and immutable) object.
This does not generalize to all predicates though. For example
Predicate<StringBuilder> check = (value) -> value.indexOf("SomeString") >= 0;
is not thread-safe. Another thread could mutate the contents of the StringBuilder argument while this predicate is checking it. The predicate could also be vulnerable to memory model related inconsistencies.
(The StringBuilder class is not thread-safe; see javadoc.)
It is not clear what you mean by "class level". Your example shows a predicate declared as a regular field, not a static (class level) field.
With a variable declared as a (mutable) instance field, it is difficult to reason about the thread-safety of the field in isolation. This can be solved by declaring the field as final.
I am learning about virtual function tables and their representation by analyzing a binary of a simple program written in Visual C++ (with some optimizations on).
A few days ago I asked this question while being stuck on virtual method table content with identical COMDAT folding on.
Now I'm stuck on something else: whenever I analyze a class, I need to find its Virtual Method Table. I can do this by finding either its RTTITypeDescriptor or _s_RTTIClassHierarchyDescriptor, finding a cross reference on it, which should lead me to the _RTTICompleteObjectLocator. When I find a cross reference to the Complete Object Locator, it is written just before the VMT (basically -1st entry of the VMT).
This approach works on some classes (their names start with C in my program). Then there are classes, that are named with I in the beginning and I am able to pair them with other classes starting with C -- for example there is class CClass and it inherits from IClass. These I-classes are probably serving as interfaces to the C-classes and thus they probably only contain abstract methods.
By searching a cross reference to Type Descriptor or Class Hierarchy Descriptor of any of the I-classes I cannot find anything -- there is no Complete Object Locator that would lead me to the VMT of the class (that should be full of references to pure_virtual call if I am correct about the all-abstract methods in the I-classes and if I understand correctly what VMT of abstract class looks like).
Why do the I-classes have no VMT? Did the compiler optimize it out because it would just be full of references to pure_virtual call and manages it in a different way?
These "interfaces" abstract classes probably have need no user written code in any their constructors and destructors (these either have an empty body and no ctor-init-list, or simply are never user defined); let's call these pure interface classes.
[Pure interface class: concept related but not identical to Java interfaces that are (were?) defined as having zero implementation code, in any member function. But be careful with analogies, as Java interfaces inheritance semantic isn't the same as C++ abstract classes inheritance semantic.]
It means that in practice no used object ever has pure interface class type: no expression ever refers to an object with pure interface type. Hence, no vtable is ever needed, so the vtable, which may have been generated during compilation, isn't included in linked code (the linker can see the symbol of the pure interface class vtable isn't used).
class SimpleTest {
void met( Object a ) {
println "Object"
}
void met( String b ) {
println "String"
}
static main( args ) {
SimpleTest i = new SimpleTest()
i.met(null)
}
}
This code will produce the output "Object". It will not choose the most specialized version of the method. In this case String is more specialized than Object, so this rule does not apply.
Groovy uses a distance calculation approach. Basically if you imagine the classes and interfaces as nodes in a graph and them being connected by their inheritance relationship, then we kind of look for the distance from our given argument type (the runtime type of the argument) to our parameter type (the static type the method parameter has). The connections have different weights, basically going to the super class means a distance of I think 3, to an interface 1, wrapping a primitive is also 1, vargs wrapping has also a weight (and cannot really be represented in the graph anymore, so sorry for the slightly failing image)
In case of null this cannot work of course. Here we look at the distance of the parameter type to Object instead. While the none-null case is the most possible special method we take for the null part the most general one instead. In Java you would normally have the static type or use a cast to ensure what is to be selected. In Groovy we don't have a static type and what is most special can often not be decided correctly. Thus we decided for the most general approach instead for that case. It works really well in general.
Object then is kind of like a fallback, that allows you central null handling. In future versions we may allow the usage of an explicit null type, which then would be preferred over Object if there.
While you can often see directly the distance approach for classes, it is a bit more complicated for interfaces. Basically the algorithm goes like this: If my current class directly implements the interface we are looking for, then it is a match with distance 1. If any of the interfaces the class implements has the interface we look for as parent, then count the "hops" till we are there as distance. But we look for the shortest distance. So we also look the same way at the super class. Any search result from there will have that distance +1 (for the super class hop). If the super class search gives a shorter distance than the search on the implementing interfaces, the super class search result will be taken instead.
As for handling null with interfaces... The distance to Object is here 1 if the interface does not extend another. If it does it is the distance of the parent interface +1. If multiple interfaces are extended, it is the shortest path again.
Let us look at List and Integer for null.
List extends Collection, Collection extend Iterable, Iterable has no parent. That makes a distance of 1 for Iterable, 2 for Collection and finally 3 for List.
Integer extends Number, Number extends Object. Since we hop two times we have a distance of 6 here (2x3), being much bigger than the other case. Yes, that means in general we prefer interfaces. We do that for practical reasons actually, since this way proofed to be most near actual programming practice.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Why isn't there generic variance for classes in C# 4.0?
Why does C# (4.0) not allow co- and contravariance in generic class types?
The new .NET 4.0 co- and contravariance for generic type arguments only works for interfaces and delegates. What is the reason for not supporting it for classes too?
For type safety, C# 4.0 supports covariance/contravariance ONLY for type parameters marked with in or out.
If this extended to classes, you'd also have to mark type parameters with in our out and this would end up being very restrictive. This is most likely why the designers of the CLR chose not to allow it. For instance, consider the following class:
public class Stack<T>
{
int position;
T[] data = new T[100];
public void Push (T obj) { data[position++] = obj; }
public T Pop() { return data[--position]; }
}
It would be impossible to annotate T as either in our out, because T is used in both input and output positions. Hence this class could never covariant or contravariant - even in C# supported covariance/contravariant type parameters for classes.
Interfaces solve the problem nicely. We can have define two interfaces as follows, and have Stack implement both:
public interface IPoppable<out T> { T Pop(); }
public interface IPushable<in T> { void Push (T obj); }
Note that T is covariant for IPoppable and contravariant for IPushable. This means T can be either covariant or contravariant - depending on whether you cast to IPoppable or IPushable.
Another reason that covariance/contravariance would be of limited use with classes is it would rule out using type parameters as fields - because fields effectively allow both input and output operations. In fact, it would be hard to write a class that does anything useful at all with a type parameter marked as in or out. Even the simplest case of writing a covariant Enumerable implementation would present a challenge - how would you get source data into the instance to begin with?
The .NET team along with the C# and VB.NET team has limited resources, the work they have done on co- and contravariance solves most of the real world problem. Type systems are very complex to get right – a solution that works in 99.9999% of cases is not good enough if it leads to unsafe code in the other cases.
I don’t think the cost/time of supporting co- and contravariance specs (e.g. “in”/”out”) on class methods is of a great enough value. I can see very few cases when they would be useable – due to the lack of multiply class inheritance.
Would you rather had waited for another 6 months for .net so as to get this support?
Another way to think of this is that in .net
Interfaces / delegates – are used to model the conceptual type system of an application
Class are used to implement the above types
Class inheritance is used to reduce code duplication while doing the above
co- and contravariance is about the conceptual type system of an application
I've heard there are differences between languages about the meaning of the keyword static, but I've not found a good list that consolidates those differences.
Here's what I know about the meaning of static in C++:
For local static variables within a function, the variable is initialized at startup and the value is saved across function calls.
Static data members are shared among all instances of a class. In other words, there is only one instance of a static data member. Static data members must be initialized at file scope.
Static member functions have access only to static members.
In recursive code, a static object or variable is guaranteed to have the same state in different instances of a block of code.
Static objects and variables defined at file scope only have internal linkage. No other files may use them.
How does the meaning of static change in other languages?
C
The keyword can change either the linkage or the duration (lifetime) of an object.
Variables are always initialized to 0
Functions have internal linkage.
If declared in file level scope: variables have internal linkage and static duration (i.e. exists throughout the lifetime of the program)
If declared in block scope: variables have no linkage but static duration
There can multiple declarations of the same static variable in a translation unit. However, note that they must be the same. E.g: at file-level scope:
int a; // a has external linkage
static int a; // a now has static linkage
// same as if you wrote: static int a = 0;
//...
static int b; // static linkage
extern int b; // extern loses its meaning, b still has internal linkage
//...
extern int b; // b has external linkage
static int b; // error
//...
void func() {
static int x; // automatic linkage, static duration
// same as if you wrote: static int x = 0;
}
C++
At file level scope the usage has been deprecated for both variables and members in favor of anonymous namespaces. Exists only as compatibility
Variables still get default initialized (as in C) to 0
"6.7 The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place [...] "
Variables have static storage duration unless accompanied by a thread_local specifier (from C++0x onwards)
There can be only one definition of a static in a translation unit
Member variables/functions mean they are properties of the class and not the instances
Legal access syntax: instance.property or Class::property
Static member functions can only access only static member variables
No this pointer for such functions
Non-static members can however access any static member
At file level objects have internal linkage except for class members which have a class scope
Class members need to be defined either in the class declaration or outside explicitly via class name and scope resolution operator
Cannot use this in a static method
ActionScript
Class methods as in C++
cannot use this or super in a static method
Accessed only through class name and not instance name
Not inherited
Derived classes however have access to bases' static properties
Variables that are declared with both the static and const keywords must be initialized at the same time as you declare the constant
Object Oriented Design
The Singleton design pattern is considered by many as a glorified static object
Used in Factory design pattern
I may have missed a lot of other things -- feel free to chip in.
In Delphi the static keyword is used exclusively for defining class methods. In Delphi a normal class method can be declared virtual and overridden in a subclass. Additionally Delphi has a self variable, similar to the this pointer in other languages. However in a class method the self points to the class in which the method is called instead of an instance.
Declaring a class method static means:
It cannot be overridden in a subclass
It does not have a self pointer
This means a static class method can only access class members in the class it was defined in, while a normal class method can access overridden class members in derived classes.
There are other informal uses of static in the Delphi documentation usually referring to a feature unchangability (is that a word?). For instance a static array vs a dynamic array. All instance methods in Delphi are static unless declared otherwise.
In C# it pretty much always means: "related to a type rather than an instance of the type".
In VB.NET, a Static variable is just like a C++ local static variable.
However, there is no class-wide Static; use Shared instead.
In C# there are 3 ways a static keyword can be used:
On class definition, which means the class will only expose static members and cannot be instanciated
On a class member, which means that the member can be called without having to instanciate the class.
On a constructor, which means that the static constructor will allways be called before a static member is called. (Those are mostly performance bottlenecks and therefore not recommended)
Hope this helps.
Python has the decorator #staticmethod, which when applied to a class member, makes the method available on the class rather than instances, and passes no automatic arguments to the method. The #classmethod decorator performs a similar function, but passes the class as the first argument, making it much more useful.
In C, static flags a function or global variable as local to the file its located in.
It's kinda like private in other languages. Sorta.
If it's in a function, then static preallocates that variable in the data section of the binary, rather than on the stack at run time.
In VB.NET static is used procedure level to mean the variable is associated with all executions of the procedure (it's preserved from call to call). That's a bit of an arcane usage in an Object-Oriented application though.
The counterpart is "Shared" which means the method or member is type level (you don't need an instance to access it).
Wikipedia summarizes many different meanings of static:
Static Methods, static variables, static typing.