views:

113

answers:

4

In the following parent class SqlStatement, how can I make Initialize() abstract but keep Execute() virtual?

using System;
using System.Collections.Generic;

namespace TestSql28374
{
    class Program
    {
        static void Main(string[] args)
        {
            object item = new object();
            List<string> properties = new List<string>();

            SqlCreateStatement sqlCreateStatement = new SqlCreateStatement(properties);
            sqlCreateStatement.Execute();

            SqlInsertStatement sqlInsertStatement = new SqlInsertStatement(item, properties);
            sqlInsertStatement.Execute();

            Console.ReadLine();
        }
    }

    public class SqlStatement
    {
        protected List<string> properties;
        protected object item;
        protected string sql;

        public SqlStatement(List<string> properties) 
        {
            this.properties = properties;
        }

        protected virtual void Initialize() //should be abstract
        { }

        public virtual void Execute()
        {
            Console.WriteLine("Sending to database: " + sql);
        }
    }

    public class SqlCreateStatement : SqlStatement
    {

        public SqlCreateStatement(List<string> properties)
            : base(properties)
        {
            Initialize();
        }

        protected override void Initialize()
        {
            sql = "CREATE TABLE...";
        }
    }

    public class SqlInsertStatement : SqlStatement
    {
        public SqlInsertStatement(object item, List<string> properties)
            : base(properties)
        {
            this.item = item;

            Initialize();
        }

        protected override void Initialize()
        {
            sql = "INSERT INTO...";
        }
    }
}
+9  A: 

Make it an abstract class

Matt Hinze
No.. have you tried this?
Matt Hinze
Nope interfaces prevent bodies. Abstract allows both.
Michael Gattuso
No, that is the joy of it! :)
Quibblesome
yes, I thought abstract classes could not have method bodies as well until I asked this question, but it works, thanks!
Edward Tanguay
+3  A: 

Declare SqlStatement as abstract.

Joe
+6  A: 

Can't you just declare it as abstract?

public abstract class SqlStatement
    {
        protected List<string> properties;
        protected object item;
        protected string sql;

        public SqlStatement(List<string> properties) 
        {
            this.properties = properties;
        }

        protected abstract void Initialize();

        public virtual void Execute()
        {
            Console.WriteLine("Sending to database: " + sql);
        }
    }
Lloyd
+1  A: 
public abstract class SqlStatement {
...
protected abstract void Initialize(); //abstract
....
}
Michael Gattuso