I have the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
abstract class parent
{
public abstract void printFirstName();
protected virtual void printLastName()
{
Console.WriteLine("Watson");
}
protected void printMiddlename()
{
Console.WriteLine("Jane");
}
}
class child: parent
{
public override void printFirstName()
{
Console.WriteLine("Mary");
}
protected override void printLastName()
{
Console.WriteLine("Parker");
}
public void getMiddleName()
{
printMiddlename();
}
}
class Program: child
{
static void Main(string[] args)
{
child ch = new child();
ch.printFirstName();
ch.getMiddleName();
//ch.printLastName();
Console.Read();
}
}
}
This code runs properly and prints Mary Jane
However, when I uncomment ch.printLastName(); it showscompile error:
Why cant my Program Class call protected method of Child Class? especially when The child class has no problem calling the protected method (printMiddleName) of Parent class?
I guess you are confusing inheritance and access levels.
Your Program class inherits the printFirstName method from child. So inside your Program class you can access that method:
class Program : child
{
void Method() { this.printFirstName(); }
}
From outside a class you cannot access protected methods. But from inside a class you can access the protected methods of instance the same type:
class Program : child
{
void Method()
{
Program p1 = new Program();
p1.printFirstName(); // this works
child c1 = new child();
p1.printFirstName(); // this gives your compiler error
}
But you cannot access a protected method of an instance of a different type, even if it is a type you derived from.
See C# Reference for more details.
C# specification Section 1.6.2 Accessibility
Each member of a class has an associated accessibility, which controls
the regions of program text that are able to access the member
public - Access not limited
protected - Access limited to this class or classes derived from this class
Protected members are accessible only in current class (where it is defined) and classes derived from it.
In another word, you can access it only by this.
printLastName is protected. Check the MSDN page about access modifiers:
protected
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
Protected keyword means that only a type and types that derive from that type can access the member.
so in this scenario you can't accesses Child.printLastName() from program Because it have two levels
Parent.printLastName() -> protected
Child.printLastName() -> protected
How inheritance work when you call Child.printLastName() from program class
it calls Parent.printLastName() -> Child.printLastName() But parent is not accessible that's the region it is showing compilation error.
Solution :-
You can make
Parent.printLastName() -> Internal access modifier
so Parent.printLastName() is accessible in this assembly .
namespace ConsoleApplication2
{
abstract class parent
{
public abstract void printFirstName();
internal virtual void printLastName()
{
Console.WriteLine("Watson");
}
public void printMiddlename()
{
Console.WriteLine("Jane");
}
}
class child : parent
{
public override void printFirstName()
{
Console.WriteLine("Mary");
}
protected override void printLastName()
{
Console.WriteLine("Parker");
}
public void getMiddleName()
{
printMiddlename();
}
}
class Program : child
{
static void Main(string[] args)
{
child ch = new child();
ch.printFirstName();
ch.getMiddleName();
ch.printLastName();
Console.Read();
}
}
}
Your code doesn't match your question - you're asking why can't Program class call protected method of it's parent (that is, child class in your example) - but your code is showing an instance of child class trying to publicly access a protected method - which fails, as intended.
This would work:
printLastName();
Or:
new Program().printLastName();
In layman's terms the method marked with protected is meaning that the class itself (child) can only access the method or other class inheriting from it.
Program calling the method off 'ch' can not access it, but an instance of Program (as its inheriting child) can call the method.
Related
I decided to change access modifier of a method which is overridden in multiple classes. So now I need to adjust accessibility modifier in all of them.
I assumed that is so common operation that Visual Studio (2019) should be able to do it automatically for me, but I couldn't find a way to do it.
Did I miss something or "manually" is the only way to go?
Not available out of the box.
Find and replace could mostly work:
Find in project/solution: public override void MyMethod(
Replace with: 'protected override void MyMethod('
Roslynator is a free/open source Visual Studio extension that has a large amount of extra refactorings, a.o. change accessibility.
For example, this changes this:
class Base
{
protected virtual void Method() { }
}
class Derived : Base
{
protected override void Method() { }
}
to this:
class Base
{
public virtual void Method() { }
}
class Derived : Base
{
public override void Method() { }
}
You could click on the x references tag above the class name to get a list of derived classes:
Just out of curiosity: are calls using the base keyword in C# dynamically bound (i.e. is it a polymorphic call)?
Consider the following example:
public class A
{
public virtual void WriteSomething()
{
Console.WriteLine("Hello from A");
}
}
public class B : A
{
public override void WriteSomething()
{
base.WriteSomething();
Console.WriteLine("Hello from B");
}
}
public class Program
{
public static void Main()
{
A instance = new B();
instance.WriteSomething();
}
}
I know that when a client (in this example the Main method) calls instance.WriteSomething, this call is dynamically bound. But what about the base.WriteSomething call in the overridden method in class B? I assume that it is not dynamically bound because the compiler knows the base class at compile time and therefore Dynamic Binding is not necessary - but I couldn't find any documentation on that.
Thanks for your help in advance!
Well I just had a look at the Intermediate Language and there one can see that the base call is not dynamically bound (the blue rectangle):
I have the following classes:
namespace ConsoleApplication8
{
public abstract class Employee
{
public virtual void Show()
{
Console.WriteLine("from base.");
}
}
public class Manager:Employee
{
public void Show()
{
Console.WriteLine("from child.");
}
}
class Program
{
static void Main(string[] args)
{
var man=new Manager();
man.Show();
Console.ReadKey();
}
}
}
Here I haven't use any override keyword for the method Show() in the derived class Manager but the code is running ok. So what is the actual use of override keyword.
You're not overriding the original method, you're hiding it. This is also possible, but maybe not what you want or what you'd expect, as you lose polymorphism. I'll give an example:
static void Main(string[] args)
{
var man=new Manager();
man.Show();
Console.ReadKey();
}
This is you code and outputs "From child". The following, when using "override" would also output "From child". In your case it will not.
static void Main(string[] args)
{
var man=new Manager();
(man as Employee).Show();
Console.ReadKey();
}
A similar question was asked here: virtual keyword in c#. While it doesn't address the override keyword, the problem class is about the same.
Real life example of when polymorphism is useful. I had to write an application to calculate the bonuses for all employees in a company based on their roles. As you did, I had an employee class with a public virtual double CalculateBonus(); method and several classed derived from that.
Thanks to Polymorphism, all I had to do is iterate the List<Employee> of all employees, regardless of their roles, and call the CalculateBonus method, as polymorphism made sure that always the overrides were called.
Without override, the bonuses would all have been 0, as that was the default result for CalculateBonus in the class Employee.
https://msdn.microsoft.com/en-us/library/ebca9ah3.aspx
https://msdn.microsoft.com/en-us/library/ms173153.aspx
you would be hiding the underlaying method so you may get a compiler warning about it and use the "new" keyword in conjunction to hide the underlaying member. override is simple - you "override" the underlaying implementation detail with your own implementation
Check the difference
void Main()
{
Person instance1=new SpecificPerson();
instance1.Execute();//Person
SpecificPerson instance2=new SpecificPerson();
instance2.Execute();//Specific
}
public class Person
{
public virtual void Execute()
{
Console.WriteLine("Person");
}
}
public class SpecificPerson:Person
{
public void Execute()
{
Console.WriteLine("Specific");
}
}
Overriding vs method hiding
I am making a simple C# console application to test inheritance but when I add 2 new classes and inherit one with another ( Mammal:Animal ) and make an object of mammal in the Program.cs class i-e
Program.cs
Mammal mam = new Mammal();
mam.see(only public function are showing of animal not the protected member of function)
Animal.cs
class Animal
{
protected void check()
{}
public void see()
{}
}
Mammal.cs
class Mammal:Animal
{
public void hair()
{}
}
Can't figure out why it is not allowing, as protected allows to inherit if they are in its hierarchy.
The code within Mammals has access to protected members of Animals, but only via an expression of type Mammals or a subtype.
From outside the class - which I assume this is - there's no access to protected members.
From section 3.5.3 of the C# 5 specification (emphasis mine):
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.
(As noted by Jonathan Reinhart, you almost certainly want these types to be called Mammal and Animal, by the way.)
Below is the way to access protected methods in derived class
class Animal
{
protected void check()
{}
public void see()
{}
}
class Mammal:Animal
{
public void CallSee()
{
Animal obja = new Animal();
obja.see();
}
}
Now you can create instance of class Mammal and call method callSee which will in turn call see method of Animal. As above answer suggestion proctected members are not accesible outside derived class. It can only be accessible in derived class
In Main Function write below code.
Static Main()
{
Mammal objm= new Mammal();
objm.CallSee();
}
The protected access modifier can be accessed only from within the declaring class or its sub classes...only public and internal makes a method accessible from outside
I have created a class say A which has some functions defined as protected.
Now Class B inherits A and class C inherits B. Class A has private default constructor and protected parameterized constructor.
I want Class B to be able to access all the protected functions defined in Class A but class C can have access on some of the functions only not all the functions and class C is inheriting class B.
How can I restrict access to some of the functions of Class A from Class C ?
EDIT:
namespace Db
{
public class A
{
private A(){}
protected A(string con){assign this value}
protected DataTable getTable(){return Table;}
protected Sqlparameters setParameters(){return parameter;}
}
}
namespace Data
{
public class B:A
{
protected B():base("constring"){}
protected DataTable output(){return getTable();}
protected sqlparameter values(param IDataParameter[] parameter){}
}
}
namespace Bsns
{
public class C:B
{
protected C():base(){}
protected DataTable show()
{return values(setparameter());}
}
}
EDIT
I think what I am trying to do here is Multiple inheritance.
Please check.
class A
{
//suppose 10 functions are declared
}
class B:A
{
//5 functions declared which are using A's function in internal body
}
class C:B
{
//using all functions of B but require only 4 functions of A to be accessible by C.
}
You need to have classes A and B in the same assembly and class C in another assembly. You can mark the member you want to restrict access to by derived classes as protected internal. This makes the member, well, protected and internal. As far as limiting class C's access to the member it will suffice to mark it internal. Since this will make it it public within the first assembly, you might want to add protected to enforce encapsulation.
Turns out marking a member protected internal doesn't make it private to classes outside of the assembly. Seems that for all intents and purposes protected internal is the same as protected. Unfortunately the only way I can see achieving this would be to mark it internal and put up with the member being public to the defining assembly.
Even C# programming guide on MSDN gets it wrong:
By combining the protected and
internal keywords, a class member can
be marked protected internal — only
derived types or types within the same
assembly can access that member.
Phil Haack explains:
protected internal means protected OR
internal
It’s very clear when you think of the
keywords as the union of accessibility
rather than the intersection. Thus
protected interna means the method is
accessible by anything that can access
the protected method UNION with
anything that can access the internal
method.
Here is the updated code:
class A {
protected void Test3(){} //available to subclasses of A in any assembly
protected internal void Test() { } //Same as protected :(
public void Test2(){}//available to everyone
internal void Test4(){} //available to any class in A's assembly
}
class B : A {
void TestA() {
Test(); //OK
}
}
//Different assembly
class C : B {
void TestA() {
Test4(); //error CS0103: The name 'Test4' does not exist in the current context
}
}
It looks like you should probably using Composition not Inheritance.
Class A implements calc() and allow().
Class B has a private A but isn't derived from A
Class C derives from B and has no access to the private A object in class B.
I'd suggest that you rethink your design. Maybe there is a simpler way. What if C uses an instance of B instead of deriving from it (composition) ? That way C can use B's public methods but not get access to the protected ones.
Class A should not care about the level/depth of a descendant. If something is marked protected, it should be protected for both B and C (regardless of the depth of the inheritance chain).
B may choose to delimit its descendants by tightening the constraints (but this is rare).
If you can tell me more about your context - the problem you are trying to solve.. I can give you a more detailed/useful answer.
As others have said, you probably want to use composition instead of inheritance.
class A {
protected void Foo() { … }
protected int Bar() { … }
}
class B {
private A a;
public B() {
this.a = new A();
}
protected int Bar() {
return a.Bar();
}
}
class C : B { … }
Looking at your example, though, I would question whether C should inherit from B, or whether it should really just hold a reference to an object of type B.
Personally, I wouldn't go putting classes in different assemblies just for the purpose of restricting access if the class doesn't otherwise logically belong in a different assembly. There are other ways to handle it.