• Tidak ada hasil yang ditemukan

Access between Static and Non-Static Members

Dalam dokumen Chapter 14. Defining Classes (Halaman 71-77)

In the chapter "High-Quality Programming Code" will we learn in details when and how to use constants efficiently.

return dogCount;

}

But when we examine how static and non-static methods and fields can be accessed, not all combinations are allowed.

Accessing Non-Static Members from Non-Static Method

Non-static methods can access non-static fields and other non-static methods of the class. For example, in the

Dog

class we can declare method

PrintInfo()

, which displays information about our dog:

Dog.cs public class Dog

{

// Static variable static int dogCount;

// Instance variables private string name;

private int age;

public Dog(string name, int age) {

this.name = name;

this.age = age;

dogCount += 1;

}

public void Bark() {

Console.Write("wow-wow");

}

// Non-static (instance) method public void PrintInfo()

{

// Accessing instance variables – name and age

Console.Write("Dog's name: " + this.name + "; age: "

+ this.age + "; often says: ");

// Calling instance method

this.Bark();

} }

Of course, if we create an object of the

Dog

class and call his

PrintInfo()

method:

static void Main() {

Dog dog = new Dog("Doggy", 1);

dog.PrintInfo();

}

The result will be the following:

Dog's name: Doggy; age: 1; often says: wow-wow

Accessing Static Elements from Non-Static Method

We can access static fields and static methods of the class from non-static method. As we learned earlier, this is because static methods and variables are bound by class, rather than a specific method and the static elements can be accessed from any object of the class, even of external classes (as long as they are visible to them).

For example:

Circle.cs

public class Circle {

public static double PI = 3.141592653589793;

private double radius;

public Circle(double radius) {

this.radius = radius;

}

public static double CalculateSurface(double radius) {

return (PI * radius * radius);

}

public void PrintSurface()

{

double surface = CalculateSurface(radius);

Console.WriteLine("Circle's surface is: " + surface);

} }

In the example, we provide access to the value of the static field

PI

of the non-static method

PrintSurface()

, by calling the static method

CalculateSurface()

. Let’s try to call this non-static method:

static void Main() {

Circle circle = new Circle(3);

circle.PrintSurface();

}

After the compilation and the execution, the following result will be printed on the console:

Circle's surface is: 28.2743338823081

Accessing Static Elements of the Class from Static Method

We can call a static method or static field of the class from another static method without any problems.

For example, let’s consider our class for mathematical calculations. We have declared the constant

PI

, in it. We can declare a static method for finding the length of the circle (the formula for finding perimeter of a circle is πr, where

r

is the radius of the circle), that uses the constant

PI

for calculating the perimeter of a circle. Then, to show that static method can call another static method, we can call the static method for finding the perimeter of a circle from the static method

Main()

:

MyMathClass.cs public class MyMathClass

{

public const double PI = 3.141592653589793;

// The method applies the formula: P = 2 * PI * r static double CalculateCirclePerimeter(double r) {

// Accessing the static variable PI from static method return (2 * PI * r);

}

static void Main() {

double radius = 5;

// Accessing static method from other static method

double circlePerimeter = CalculateCirclePerimeter(radius);

Console.WriteLine("Circle with radius " + radius + " has perimeter: " + circlePerimeter);

} }

The code is compiled without errors and displays the following output:

Circle with radius 5.0 has perimeter: 31.4159265358979

Accessing Non-Static Elements from Static Method

Let’s look at the most interesting case of a combination of accessing non- static and static elements of the class – accessing non-static elements form a static method.

We should know that from static method we can neither access non-static fields, nor call non-static methods. This is because static methods are bound to the class and do not “know” any object of the class. Therefore, the keyword

this

cannot be used in static methods – it is bound to a specific instance of the class. When we try to access non-static elements of the class (fields or methods) from static method, we will always get a compilation error.

Unauthorized Access to Non-Static Field – Example

If in our class

Dog

we try to declare a static method

PrintName()

, which returns as a result the value of the non-static field

name

declared in the class:

public static void PrintName() {

// Trying to access non-static variable from static method Console.WriteLine(name); // INVALID

}

Accordingly, the compiler will respond with an error message:

An object reference is required for the non-static field, method, or property 'Dog.name'

If we try to access the field in the method, via the keyword

this

:

public void string PrintName() {

// Trying to access non-static variable from static method Console.WriteLine(this.name); // INVALID

}

The compiler will still not be satisfied and this time will fail to compile the class and will display the following message:

Keyword 'this' is not valid in a static property, static method, or static field initializer

Illegal Call of Non-Static Method from Static Method – Example Now we will try to call non-static method from static method. Let declare in our class

Dog

, the non-static method

PrintAge()

, which prints the value of the field

age

:

public void PrintAge() {

Console.WriteLine(this.age);

}

Accordingly, let’s try from the method

Main()

, which we declare in the class

Dog

, to call this method without creating an object of our class:

static void Main() {

// Attempt to invoke non-static method from a static context PrintAge(); // INVALID

}

When we try to compile we will get the following error:

An object reference is required for the non-static field, method, or property 'Dog.PrintAge()'

The result is similar, if we try to cheat the compiler, trying to call the method via the keyword

this

:

static void Main() {

// Attempt to invoke non-static method from a static context this.PrintAge(); // INVALID

}

Accordingly, as with the attempt to access the non-static field of a static method using the keyword

this

, the compiler displays the following error message and fails to compile our class:

Keyword 'this' is not valid in a static property, static method, or static field initializer

From the examples, we can make the following conclusion:

Non-static elements of the class may NOT be used in a static context.

The problem with the access to non-static elements of the class of static method has a single solution – these non-static elements are accessed by reference to an object:

static void Main() {

Dog myDog = new Dog("Lassie", 2);

string myDogName = myDog.name;

Console.WriteLine("My dog \"" + myDogName +"\" has age of ");

myDog.PrintAge();

Console.WriteLine("years");

}

Accordingly, this code is compiled and the result is:

My dog "Lassie" has age of 2 years

Dalam dokumen Chapter 14. Defining Classes (Halaman 71-77)

Dokumen terkait