please explain me how this code is working and why it will trough an error in class B
public class A
{
protected int x;
static void F(A a, B b) {
a.x = 1; // Ok
b.x = 1; // Ok
}
}
public class B: A
{
static void F(A a, B b) {
a.x = 1; // Error, must access through instance of B
b.x = 1; // Ok
}
}
Code in B can only access a protected variable through an expression which has a compile-time type of B or some type derived from B. That's basically how protected access works.
From section 3.5.3 of the C# 4 language specification:
When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.
The protected keyword is a member
access modifier. A protected member
is accessible from within the class in
which it is declared, and from within
any class derived from the class
that declared this member.
public class A
{
public int x;
public static void F(A a, B b)
{
a.x = 1;
b.x = 1;
}
}
public class B : A
{
public static void F(A a, B b)
{
a.x = 1;
b.x = 1;
}
}
Why I redefined it with public access modifier. protected modifier has restricted access to inherit class blocks.
Class A {
protected int x = 0;
}
Class B : A {
private void SomeFunc() {
Console.WriteLine(this.x.ToString()); // This will work!
}
}
But if you try to access x you'll get nothing in B.
B b = new B();
b.x; // Got nothing in IntelliSense
See we got the access of x in a function of B but it's instance has no access of x.
Related
I am new to C++. How do you create a method within one class which initializes an object within another class with specified parameters? Something like the following.
class A {
public:
double X;
double Y;
A(double a, double b) {
X = a;
Y = b;
};
class B {
public:
A f(double a, double b) {
//Initialize an object of type A using parameters specified.
};
};
I want to use the object of type A later so, presumably, I would need to use the new operator within f. Thanks in advance.
Try this:
class B {
public:
A* f(double a, double b) { return new A(a, b); };
};
Although you could just as easily do new A(a,b) anywhere you wanted to do B.f(a,b).
I have a class that takes one of its subclasses as an argument. When constructing that subclass, I want to be able to use this as the value of that argument:
class A(val b: B)
class B extends A(this)
However, this fails to compile
this can be used only in a class, object, or template
[error] class B extends A(this)
[error] ^
Is there any way to get around this? I'm pretty sure that a pattern like this can be written in Java.
I'm not so sure about the last statement:
public class MyClass {
static class A {
A(B b) {
System.out.println(b.value);
}
}
static class B extends A {
String value;;
B() {
super(this);
value = "x";
}
}
public static void main(String args[]) {
new B();
}
}
gives the following error:
/MyClass.java:10: error: cannot reference this before supertype constructor has been called
super(this);
^
There is no good reason to attempt to let the this reference escape the scope of the constructor before the object itself has been constructed. Refactor it.
In typescript, for an interface, is there a way to enforce the type of a property to be the "child subclass C, that extends class P"?
example.ts
import { P } from '/path/to/types'
class C extends P {
...
}
types.ts
// `C` is not accessible here
class P {
...
}
interface {
myProp: ???? <-- how to enforce `myProp` is a subclass of P (class, not instance)?
}
Alternatively, I can check Object.getPrototypeOf(myProp.prototype) === P.prototype, but that is at runtime. Is there a way to enforce this condition via types during compile/checker time?
You can use typeof to get the type:
class P { ... }
interface Foo {
myProp: typeof P
}
//Usage
class C extends P { ... }
class D { ... }
//Ok
var f: Foo = {
myProp: C
}
// Error
var f2: Foo = {
myProp: D
}
This will ensure that the class specified as the property will be compatible with P.
Edit
Since Typescript uses structural compatibility, any class that has the same structure as P will be compatible with typeof P. If P has only public members and a small number of members, there may be a risk that another class may unwittingly have the same structure. To ensure that only classes directly inheriting P are compatible, you can add a private member to P that makes P incompatible with other classes (even ones with the same structure, different declarations of private fields are not compatible with each other)
class P { private nonStructural:true }
interface Foo {
myProp: typeof P
}
//Usage
class C extends P { }
class D { private nonStructural:true }
//Ok
var f: Foo = {
myProp: C
}
// Error
var f2: Foo = {
myProp: D
}
I'm having a bit of trouble locating any clear documentation or explanation for the seemingly-special relationship between a TypeScript class and an interface with the same name.
What's the significance of an interface with the same name as a class?
Why does a class that shares its name with an interface implement that interface automatically?
Why does the compiler complain about my getter implementation of a readonly interface field when the class and interface have the same name, but accept the implementation if the names are different?
Is there any canonical documentation addressing these questions?
Code:
// Co-named interface and class doesn't like readonly property implementation:
interface Foo {
readonly x: number; // Error: Duplicate identifier 'x'
y: number;
}
class Foo {
get x(): number { // Error: Duplicate identifier 'x'
return 0;
}
y = 1;
}
// Same as above, but different class name + explicit `implements`
class Bar implements Foo {
get x(): number { // No error!
return 0;
}
y = 1;
}
// Duplicating the first example, but explicitly implementing the co-named interface:
interface Baz {
readonly x: number; // Error: Duplicate identifier 'x'
y: number;
}
class Baz implements Baz {
get x(): number { // Error: Duplicate identifier 'x'
return 0;
}
y = 1;
}
Interfaces of the same name within a module will be merged:
interface Foo {
x: number;
}
interface Foo {
y: string;
}
let g = {} as Foo;
g.x; // OK
g.y; // OK
A class declaration creates both a constructor function as well as type declaration, which essentially means that all classes can be used as interfaces.
class Bar {
y: number;
}
interface IBaz extends Bar { } // includes y: number
class CBaz implements Bar {
y: number = 5;
}
Therefore, having a class and an interface with the same name is equivalent to having two interfaces with the same name, and you will get merge conflicts if both instances of the interface re-declare the same members with different types.
Strangely enough, Typescript will allow for this:
export interface Foo {
readonly x: number;
}
export class Foo {
readonly x: number = 3;
}
but it won't allow get x() { return 3; } even though both of those generate as readonly x: number, so I can only imagine that the type checker considers them as different during merging even though they are semantically the same (this is why you can extend the interface and specify the readonly property as a getter function).
This is a limitation specific to accessors, and so far the Typescript team appears unwilling to comment on the issue.
class Foo {
readonly x: number = 0;
}
class Bar extends Foo {}
interface Bar {
readonly x: 2;
}
const bar = new Bar();
bar.x; // type is 2, no error
The team has commented that "[w]hether a property is implemented as a field or a getter/setter pair is an implementation detail, not part of the type," but this is clearly not the case as of Typescript 4.2:
class Baz extends Foo {
// error: "'x' is defined as a property in class 'Foo',
// but is overridden here in 'Baz' as an accessor."
get x() {
return 2;
}
}
I have no explanation for the team's responses. The comment that getters/setters are not part of the type system is from 2015 and may simply be outdated.
I'm having some trouble with deriving a pointer to a derived class. I think it has something to do with a constructor. Do I have to create a new constructor in my derived class? How to I create a pointer from a derived class? Thanks
Class Base
{
public:
int myfunction(int a,int b,int c)
{
return a+b+c;
}
};
Class Derived: public Base
{
int newfunction(int a, int b, int c)
{
return a*b*c;
};
};
int main()
{
// this doesn't work at all.. I get all errors every time I try to refer to the object
//instantiated from my derived class.
//I know it's my lack of understanding.
Derived *NewObject = new Derived;
//Why wont this work?
}
C++ is case sensitive, and the keyword class is lowercase. You wrote Class for both classes, and it looks like it's the only issue with your code.