VB.NET101 - Constructors and Methods (2)

G

Guest

Before anything else, thanks Marina, Workgroups and Ralf, for your help so far.
I am now able to better define the question!

After adding more console printout lines to CSum, I tried all permutations
for constructors (none, default, two argument) and method call in body of
constructor (none and one).
Maybe this example is not representative, but for this example I found the
following:
1. Without any constructors, the program works fine (new object
instantiated, method called, sum calculated, no build errors listed).
2. With two constructors (empty and two arguments ones), the program works
fine as well.
3. With only the empty constructor, the program also works fine.
4. With only the two argument constructor, the program works, but lists the
build error: ‘Arguments not specified for parameters “first†(and “secondâ€)
of Public Sub New(first As Integer, second As Integer)’. Note: The “Why?†for
this was my original posted question!
5. The only difference using a method call Sum(0,0) in a constructor is that
the Sum method calculates it’s result using two zero arguments before the
arguments listed in Main are passed on to Sum.
6. If used, the Console.WriteLine method placed in the body of the two
argument constructor is never printed. Hence, it looks like the program
pointer never runs though this constructor. Why?

See 1st attachment below.

I also used overloaded methods in the 2nd attachment, with basically the
same results; the method calls for both the two and three argument methods
worked fine without the use of any constructors (so no constructors needed to
make overloading possible!)

The main remaining question is: What is the added value of using a
constructor?
I am sure there must be good reasons why constructors are used and that they
are used for features which otherwise cannot be dealt with.

Your explanation is highly appreciated,

Regards,

John
(Attachment 1)

Module Module1
Sub Main()

Dim thisFirstNumber As Integer = 10
Dim thisSecondNumber As Integer = 100

Dim thisSum As New CSum

thisSum.Sum(thisFirstNumber, thisSecondNumber)

End Sub
End Module

Public Class CSum

Public mSum As Integer = 1

'Public Sub New() 'Empty
constructor
'Console.WriteLine("After entering empty constructor, value of mSum =
{0}", mSum)
'Console.WriteLine("Program pointer jumps to Sum method after this line
to calc Sum(0,0).")
'Sum(0, 0)
'Console.WriteLine("Leaving empty constructor")
'Console.WriteLine()
'End Sub

'Public Sub New(ByVal first As Integer, ByVal second As Integer) 'Two
argument constructor
'Console.WriteLine("After entering 2-par. constructor, value of mSum =
{0}", mSum)
'Console.WriteLine("Program pointer jumps to Sum method after this line
to calc Sum(0,0).")
'Sum(0, 0)
'Console.WriteLine("Leaving 2-par. constructor")
'Console.WriteLine()
'End Sub

Public Sub Sum(ByVal first As Integer, ByVal second As Integer)
'Sum method
Console.WriteLine("Value of mSum before using formula is: {0}", mSum)
mSum = first + second
Console.WriteLine("After using Sum formula: The sum of {0} and {1} =
{2}", first, second, mSum)
End Sub

End Class

(Attachment 2)

Module Module1
Sub Main()

Dim thisFirstNumber As Integer = 10
Dim thisSecondNumber As Integer = 100
Dim thisLastNumber As Integer = 1000

Dim thisSum As New CSum

thisSum.Sum(thisFirstNumber, thisSecondNumber)

thisSum.Sum(thisFirstNumber, thisSecondNumber, thisLastNumber)

End Sub
End Module

Public Class CSum

Public mSumOfTwo As Integer = 1
Public mSumOfThree As Integer = 2

Public Sub New() 'Empty constructor
Console.WriteLine("Value mSumOfTwo after entering empty constructor
is: {0} " _
, mSumOfTwo)
Sum(3, 4)
Console.WriteLine("Value mSumOfTwo after Sum(0,0) in empty constructor
is: {0} " _
, mSumOfTwo)
Console.WriteLine("Value mSumOfThree after entering the empty
constructor is: {0} " _
, mSumOfThree)
Sum(5, 6, 7)
Console.WriteLine("Value mSumOfThree after Sum(5,6,7) in empty
constructor is: {0} " _
, mSumOfThree)
Console.WriteLine()
End Sub

'Two argument CSum constructor
'Public Sub New(ByVal first As Integer, ByVal second As Integer)
'Console.WriteLine("Value mSumOfTwo after entering two argument
constructor is: {0} " _
' , mSumOfTwo)
'Console.WriteLine()
'Sum(0, 0)
'End Sub

'Three argument CSum constructor
Public Sub New(ByVal first As Integer, ByVal second As Integer, ByVal
third As Integer)
Sum(0, 0, 0)
End Sub

Public Sub Sum(ByVal first As Integer, ByVal second As Integer)

Console.WriteLine("Value mSumOfTwo before using the addition formula
is: {0} " _
, mSumOfTwo)

mSumOfTwo = first + second

Console.WriteLine("The sum of {0} and {1} = {2}", _
first, second, mSumOfTwo)
Console.WriteLine()
End Sub

Public Sub Sum(ByVal first As Integer, ByVal second As Integer, ByVal
third As Integer)

Console.WriteLine("Value mSumOfThree before using the addition formula
is: {0} " _
, mSumOfThree)

mSumOfThree = first + second + third

Console.WriteLine("The sum of {0} and {1} and {2} = {3}", _
first, second, third, mSumOfThree)
Console.WriteLine()
End Sub

End Class

******************************************************
Again, thanks for your support,
John
 
A

_AnonCoward

:
: Before anything else, thanks Marina, Workgroups and Ralf, for your
: help so far. I am now able to better define the question!


If you do not specify an empty constructor, the compiler generates one
for you. The rules as to how that works depends on how you define your
class.



In a nutshell,

- If you include an empty constructor for your class,
the compiler will use that

- If you don't supply an empty constructor in your
class, the compiler will automatically add one for you.

* If there aren't any constructors defined for your
class, the compiler generated constructor will be
public.

* If you define at least one parameterized constructor
for your class, the compiler generated empty constructor
will be private.


: After adding more console printout lines to CSum, I tried all
: permutations for constructors (none, default, two argument) and
: method call in body of constructor (none and one).
:
: Maybe this example is not representative, but for this example I found
: the following:
:
: 1. Without any constructors, the program works fine (new object
: instantiated, method called, sum calculated, no build errors
: listed).


Since you didn't specify a constructor, the compiler inserted one for
you. In this case, it was public by default


'functional equivalent of compiler supplied
'default constructor

Public Sub New
End Sub


: 2. With two constructors (empty and two arguments ones), the program
: works fine as well.
: 3. With only the empty constructor, the program also works fine.



In these two cases, you supplied the empty constructor so there wasn't
an issue.


: 4. With only the two argument constructor, the program works, but
: lists the build error: 'Arguments not specified for parameters
: "first" (and "second") of Public Sub New(first As Integer, second
: As Integer)'. Note: The "Why?" for this was my original posted
: question!


Here is where you ran into a snag. Since you did not supply an empty
constructor, the compiler added one for you. However, it assumed that
since you didn't specify an assessible empty constructor, you didn't
want one so the constructor it supplied was private


'functional equivalent of compiler supplied
'default constructor

Private Sub New
End Sub


: 5. The only difference using a method call Sum(0,0) in a constructor
: is that the Sum method calculates it's result using two zero
: arguments before the arguments listed in Main are passed on to Sum.
:
: 6. If used, the Console.WriteLine method placed in the body of the two
: argument constructor is never printed. Hence, it looks like the
: program pointer never runs though this constructor. Why?


This constuctor is actually superfluous to your class. The reason the
console.writeline statements weren't invoked is because you never
actually called them. In your sub main, your code looks like this:


-------------------------------------
Sub Main()

Dim thisFirstNumber As Integer = 10
Dim thisSecondNumber As Integer = 100
Dim thisLastNumber As Integer = 1000

Dim thisSum As New CSum

thisSum.Sum(thisFirstNumber, thisSecondNumber)

thisSum.Sum(thisFirstNumber, thisSecondNumber, thisLastNumber)

End Sub
-------------------------------------


You only create one instance of the CSum class and it calls the
parameterless constructor. If you'd used the following instead, you'd
see a different result:


Dim thisSum As New CSum(1, 2)


The following is from the microsoft MSDN site which offers a more formal
explanation of how constructors work:


http://tinyurl.com/bjpwr

(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/
html/vblrfVBSpec7_2_1.asp)


"Instance constructors initialize instances of a type and are
run by the .NET Framework when an instance is created. The
parameter list of a constructor is subject to the same rules as
the parameter list of a method. Instance constructors may be
overloaded.


"All constructors in reference types must invoke another constructor.
If the invocation is explicit, it must be the first statement in the
constructor method body. The statement can either invoke another of
the type's instance constructors - for example, Me.New(...) or
MyClass.New(...) - or if it is not a structure it can invoke an
instance constructor of the type's base type - for example,
MyBase.New(...). It is invalid for a constructor to invoke itself.
If a constructor omits a call to another constructor, MyBase.New()
is implicit. If there is no parameterless base type constructor, a
compile-time error occurs. Because Me is not considered to be
constructed until after the call to a base class constructor,
the parameters to a constructor invocation statement cannot
reference Me, MyClass, or MyBase implicitly or explicitly.


"When a constructor's first statement is of the form MyBase.New(...),
the constructor implicitly performs the initializations specified by
the variable initializers of the instance variables declared in the
type. This corresponds to a sequence of assignments that are
executed immediately after invoking the direct base type
constructor. Such ordering ensures that all base instance variables
are initialized by their variable initializers before any statements
that have access to the instance are executed.


"When a type declares only Private constructors, it is not possible
in general for other types to derive from the type or create
instances of the type; the only exception is types nested within the
type. Private constructors are commonly used in types that contain
only Shared members.


"If a type contains no instance constructor declarations, a default
constructor is automatically provided. The default constructor
simply invokes the parameterless constructor of the direct base
type. If the direct base type does not have an accessible
parameterless constructor, a compile-time error occurs. The
declared access type for the default constructor is always Public."



HTH


Ralf
--
 
G

Guest

Hi John,

I have not been following the full discussion, but the constructor will be
called only when the class is created. Here when you create the class you do
not pass any arguments. So the constructor with two arguments will never be
called.

If you do something like

Dim c as csum = new csum(1,2)

Then the overloaded constructor will be called.
 
A

_AnonCoward

I need to correct part of my comments. For some reason, I had a brain
fart and stated (several times, in fact) that the compiler will supply a
private empty constructor in certain situations. On reflection, I
realize it doesn't. I have no idea where I got that notion from.


If a class is defined without any constructors, a public empty
constructor is added by the compiler. However, if they class includes at
least one parameterized constructor, the compiler will *not* insert an
empty constructor. In that case, there is no parameterless constructor
and so the statement


Dim thisSum As New CSum


fails because there isn't a Public Sub New for this to invoke.


Ralf



:
: : :
: : Before anything else, thanks Marina, Workgroups and Ralf, for your
: : help so far. I am now able to better define the question!
:
:
: If you do not specify an empty constructor, the compiler generates one
: for you. The rules as to how that works depends on how you define your
: class.
:
:
:
: In a nutshell,
:
: - If you include an empty constructor for your class,
: the compiler will use that
:
: - If you don't supply an empty constructor in your
: class, the compiler will automatically add one for you.
:
: * If there aren't any constructors defined for your
: class, the compiler generated constructor will be
: public.
:
: * If you define at least one parameterized constructor
: for your class, the compiler generated empty constructor
: will be private.
:
:
: : After adding more console printout lines to CSum, I tried all
: : permutations for constructors (none, default, two argument) and
: : method call in body of constructor (none and one).
: :
: : Maybe this example is not representative, but for this example I
: : found
: : the following:
: :
: : 1. Without any constructors, the program works fine (new object
: : instantiated, method called, sum calculated, no build errors
: : listed).
:
:
: Since you didn't specify a constructor, the compiler inserted one for
: you. In this case, it was public by default
:
:
: 'functional equivalent of compiler supplied
: 'default constructor
:
: Public Sub New
: End Sub
:
:
: : 2. With two constructors (empty and two arguments ones), the program
: : works fine as well.
: : 3. With only the empty constructor, the program also works fine.
:
:
:
: In these two cases, you supplied the empty constructor so there wasn't
: an issue.
:
:
: : 4. With only the two argument constructor, the program works, but
: : lists the build error: 'Arguments not specified for parameters
: : "first" (and "second") of Public Sub New(first As Integer, second
: : As Integer)'. Note: The "Why?" for this was my original posted
: : question!
:
:
: Here is where you ran into a snag. Since you did not supply an empty
: constructor, the compiler added one for you. However, it assumed that
: since you didn't specify an assessible empty constructor, you didn't
: want one so the constructor it supplied was private
:
:
: 'functional equivalent of compiler supplied
: 'default constructor
:
: Private Sub New
: End Sub
:
:
: : 5. The only difference using a method call Sum(0,0) in a constructor
: : is that the Sum method calculates it's result using two zero
: : arguments before the arguments listed in Main are passed on to
: : Sum.
: :
: : 6. If used, the Console.WriteLine method placed in the body of the
: : two
: : argument constructor is never printed. Hence, it looks like the
: : program pointer never runs though this constructor. Why?
:
:
: This constuctor is actually superfluous to your class. The reason the
: console.writeline statements weren't invoked is because you never
: actually called them. In your sub main, your code looks like this:
:
:
: -------------------------------------
: Sub Main()
:
: Dim thisFirstNumber As Integer = 10
: Dim thisSecondNumber As Integer = 100
: Dim thisLastNumber As Integer = 1000
:
: Dim thisSum As New CSum
:
: thisSum.Sum(thisFirstNumber, thisSecondNumber)
:
: thisSum.Sum(thisFirstNumber, thisSecondNumber, thisLastNumber)
:
: End Sub
: -------------------------------------
:
:
: You only create one instance of the CSum class and it calls the
: parameterless constructor. If you'd used the following instead, you'd
: see a different result:
:
:
: Dim thisSum As New CSum(1, 2)
:
:
: The following is from the microsoft MSDN site which offers a more
: formal explanation of how constructors work:
:
:
: http://tinyurl.com/bjpwr
:
:
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/
: html/vblrfVBSpec7_2_1.asp)
:
:
: "Instance constructors initialize instances of a type and are
: run by the .NET Framework when an instance is created. The
: parameter list of a constructor is subject to the same rules as
: the parameter list of a method. Instance constructors may be
: overloaded.
:
:
: "All constructors in reference types must invoke another
: constructor. If the invocation is explicit, it must be the first
: statement in the constructor method body. The statement can either
: invoke another of
: the type's instance constructors - for example, Me.New(...) or
: MyClass.New(...) - or if it is not a structure it can invoke an
: instance constructor of the type's base type - for example,
: MyBase.New(...). It is invalid for a constructor to invoke itself.
: If a constructor omits a call to another constructor, MyBase.New()
: is implicit. If there is no parameterless base type constructor, a
: compile-time error occurs. Because Me is not considered to be
: constructed until after the call to a base class constructor,
: the parameters to a constructor invocation statement cannot
: reference Me, MyClass, or MyBase implicitly or explicitly.
:
:
: "When a constructor's first statement is of the form
: MyBase.New(...),
: the constructor implicitly performs the initializations specified
: by the variable initializers of the instance variables declared in
: the type. This corresponds to a sequence of assignments that are
: executed immediately after invoking the direct base type
: constructor. Such ordering ensures that all base instance
: variables are initialized by their variable initializers before
: any statements
: that have access to the instance are executed.
:
:
: "When a type declares only Private constructors, it is not possible
: in general for other types to derive from the type or create
: instances of the type; the only exception is types nested within
: the type. Private constructors are commonly used in types that
: contain only Shared members.
:
:
: "If a type contains no instance constructor declarations, a default
: constructor is automatically provided. The default constructor
: simply invokes the parameterless constructor of the direct base
: type. If the direct base type does not have an accessible
: parameterless constructor, a compile-time error occurs. The
: declared access type for the default constructor is always
: Public."
:
:
:
: HTH
:
:
: Ralf
: --
: ----------------------------------------------------------
: * ^~^ ^~^ *
: * _ {~ ~} {~ ~} _ *
: * /_``>*< >*<''_\ *
: * (\--_)++) (++(_--/) *
: ----------------------------------------------------------
: There are no advanced students in Aikido - there are only
: competent beginners. There are no advanced techniques -
: only the correct application of basic principles.
:
:
:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top