0

Just wanted to ask generic question about Namespaces. If class A inherits class B and doesn't explicitly reference (using) B's namespace, do I have to explicitly using B namespace in my calling code to call B's methods from an instance of A? Is this language dependent (C#, C++)?

Ex in C#:

// Namespace X
class A : B 
{
    public void methodA(){...}
}

// Namespace Y
class B
{
    public void methodB(){...}
}

In other code using A:

using X;
// do I need using Y?
...
A obj = new A();
obj.methodB(); // calls methodB() using instance of A
...
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Ninja
  • 1,012
  • 3
  • 14
  • 29
  • @EdPlunkett since A is a child of B, I can reference/call public/protected fields/methods/properties in B using object A. So what I mean is that using my object A, i would like to call a function defined in B. – Ninja Aug 29 '19 at 16:46
  • 1
    The fact that we're all giving such different answers to your question illustrates the fact that your question is very vague and open to misinterpretation. We're all interpreting it different ways. Can you make your question clearer? – cdhowie Aug 29 '19 at 16:52
  • @cdhowie yes, let me try to edit the question. Sorry for confusion. – Ninja Aug 29 '19 at 16:59
  • 1
    @Ninja Please show code which demonstrates what you are referring to. "Using object A" is ambiguous. *How* are you "using" object A? And what does that have to do with `using` in any case? – 15ee8f99-57ff-4f92-890c-b56153 Aug 29 '19 at 17:03
  • @EdPlunkett updated – Ninja Aug 29 '19 at 17:10
  • 2
    I suggest that you remove one language tag (and possibly ask a separate question for that language). You can then compare the answers to find out if there's a difference. – Ted Lyngmo Aug 29 '19 at 17:12
  • 1
    What Ted Lyngmo said. Please ask about one language at a time. – HolyBlackCat Aug 29 '19 at 17:14
  • 1
    @TedLyngmo Sure, sorry for confusion. – Ninja Aug 29 '19 at 17:17

4 Answers4

2

if A is in namespace X and B in Y, you can't do

// Namespace X
class A : B 
{
...
};

you need to do:

class A : Y::B 
{
...
};

So you see you had to inherit B using the qualification and there's nothing special going on there. This is in C++ btw.

If A needs anything more from Y it'll need to similarly qualify it.

Anybody using A needs to qualify it with X::A or import everything or just A, depending, to use it - using X::A; or using namespace X;. That has no effect on what happens to the visibility of things inside Y though.

The only thing that might surprise you is Koenig Lookup, so maybe read that.

ustulation
  • 3,600
  • 25
  • 50
  • Thanks for information! Ah I wrote my example in C#, maybe syntax is different in C++. @ustulation besides `class A : Y::B` change, in my calling code, I also need to explicitly define `using Y`to call methods in class B from object A? – Ninja Aug 29 '19 at 16:58
  • No, `B` is now visible to you now (well it's a subobject inside of an instance of`A` so it better be :) ). You can call static and non-static mem. functions in `B` from mem functions of `A` without any namespace `Y` qualifications. – ustulation Aug 29 '19 at 17:03
2

No namespaces are not inherited by classes in C++ (and in C#). However due to the ADL (Argument Dependent Lookup) you can "inherit" some names from the namespace of a base class.

Here is a demonstrative program

#include <iostream>

namespace N1
{
    struct A {};

    void f( const A & )
    {
        std::cout << "N1::f( const A & )\n" << '\n';
    }
}

namespace N2
{
    struct B : N1::A
    {
        B() { f( *this ); }
    };
}

int main() 
{
    N2::B b;

    return 0;
}

Its output is

N1::f( const A & )

To "inherit" a namespace you can use the using directive in a namespace or in a block scope. For example

namespace N1
{
    struct A {};
}

namespace N2
{
    using namespace N1;

    struct B : A
    {
    };
}

Take into account that you may not use the using directive in a class scope.

Or you can introduce only some names by means of a using declaration.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • so you are saying that `using namespace N1;` in your code is not necessary, but can be added? Is this specific for C++? – Ninja Aug 29 '19 at 17:15
  • 1
    @Ninja In the first example I used the qualified name in the dericved class declaration struct B : N1::A. In this case the using directive is not required. Also the using directive is not required if an unqualified name can be found by ADL as with the function f. In the second example due to the using directive using namespace N1; I can use unqualified name of the base class. – Vlad from Moscow Aug 29 '19 at 17:18
  • ah so difference is: qualified vs unqualified name. Thanks for response for C++, i wonder if same is true for C#. – Ninja Aug 29 '19 at 17:21
  • @Ninja Yes it is true for C#. Only there is no ADL. – Vlad from Moscow Aug 29 '19 at 17:21
1

Classes do not inherit namespaces. using only imports the symbols in a namespace into the current source file. It has no effect on your classes themselves.

This C# code:

using System;

public class A {
    public void Run() {
        Console.WriteLine("Foobar");
    }
}

Is completely equivalent in its effects, both in the CIL emitted as well as how users of A will use the class or derive it, to this code:

public class A {
    public void Run() {
        System.Console.WriteLine("Foobar");
    }
}

Let's say that we import a type that we return from a method:

using System.IO;

public class A {
    public Stream createStream() {
        // implementation irrelevant
    }
}

If we then declare class B : A in another source file, the createStream() method is inherited, and it still returns System.IO.Stream, even if the source file B is declared in doesn't have using System.IO, and users of class B do not need to import System.IO in order to use the stream returned by createStream(); the system knows the fully-qualified type is System.IO.Stream.

public class B : A {
    public void doSomethingWithStream() {
        // We can use a System.IO.Stream object without importing System.IO
        using (var s = createStream()) {
        }
    }
}

public class C {
    public static void doSomethingElseWithStream(B b) {
        // As can other stuff that uses B.
        using (var s = b.createStream()) {
        }
    }
}
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • thanks for useful response. I understand your point, I think I was a bit confused about when using needs to be explicitly defined. If A is subclass of B, i guess namespace A lives in needs to reference namespace B lives in? If that is not true, then when user creates an object of A and calls B's methods directly (without full namespace), he needs to reference both namespaces? – Ninja Aug 29 '19 at 16:54
  • @Ninja If A is a subclass of B then the user of the class doesn't need to know anything about what namespaces B may or may not reference. All of the public symbols defined in the B class are inherited by A. The namespaces imported into the file B is defined in are _not_ inherited, but that doesn't matter. – cdhowie Aug 29 '19 at 16:59
  • I guess I am not understanding, you just mentioned that classes do not inherit namespaces... So therefore, A will not have knowledge of namespaces that B uses/references. – Ninja Aug 29 '19 at 17:03
  • @Ninja _"So therefore, A will not have knowledge of namespaces that B uses/references."_ Not inherently. – πάντα ῥεῖ Aug 29 '19 at 17:05
  • 1
    @Ninja That is correct. However, for example, the types of return values in methods declared on B that are inherited by A will also be present in A, but _how_ that type was referenced in the B source file is totally irrelevant. Importing a namespace is just a convenience for the developer of class B; _it doesn't actually change anything about class B._ – cdhowie Aug 29 '19 at 17:17
  • @Ninja I have updated by answer with another C# example that may help to clarify. (I've also removed the C++ section.) – cdhowie Aug 29 '19 at 17:20
  • @cdhowie Do not remove the C++ tag because it will confuse readers of the question because initially this tag was present. – Vlad from Moscow Aug 29 '19 at 17:24
  • @VladfromMoscow The heck!? I did not remove the tag, I only removed the section of my answer that discussed C++. OP removed the tag. This is clearly visible in the question edit history. – cdhowie Aug 29 '19 at 17:24
0

No, there is no such thing as a inherited namespace. Namespace does not have anything that can be derived/inherited.

If you want to inherit a class A that is in different namespace, you need to add "using namespace ..."

Djuro
  • 384
  • 2
  • 9
  • Ah you are saying that if A inherits B, then namespace of A itself needs to `using` the namespace that B lives in. So if this is the case, there is no need to write `using Y` in my calling code. I just need to `using X` because namespace X already references namespace Y. Is this your meaning? – Ninja Aug 29 '19 at 16:50
  • Oh, if you have a class from namespace A that derives from class in namespace B, in class definition you need to have using B. If you are in namespace C, and you use using namespace A, you can use that class that derived from namespace B. But that doesnt mean that you can use everything from namespace B, just that class you derived from. – Djuro Aug 29 '19 at 17:24