freepascal Наследование: Error: Duplicate identifier - Ошибка

Наблюдаю ошибки при переопределении конструктора - видимо конфликт имен с именами полей, но проявляется почему-то только при наследовании (?)

project28.lpr(286,37) Error: Duplicate identifier "moveLeftChar"
project28.lpr(286,51) Error: Duplicate identifier "moveRightChar"
project28.lpr(293,37) Error: Duplicate identifier "moveLeftChar"
project28.lpr(293,51) Error: Duplicate identifier "moveRightChar"

Код (урок по преопределениею методв в ООП):

uses Crt; //  импортираем модуль Crt

type
  Animal = class
    public
      constructor create(skinValue, moveLeftChar, moveRightChar: char);
      procedure drawFrame();
      procedure handleCommand(commandValue: char);
      function getCommand(): char;
      function getPosition(): integer;
      function isCurrentPosition(position: integer): boolean;
    protected
      moveLeftChar: char; // клавиша (символ) для движения влево
      moveRightChar: char; // клавиша (символ) для движения вправо
      skin: char; // внешний вид
      position: integer; // текущая позиция
      command: char; // последняя введенная команда
      function getNewPosition(commandValue: char): integer;
  end;

  D1Animal = class(Animal)
    public
      constructor create(skinValue, moveLeftChar, moveRightChar: char);
    protected
      vertposition: integer;
  end;

  D2Animal = class(Animal)
    public
      constructor create(skinValue, moveLeftChar, moveRightChar: char);
      function getVertPosition():integer;
      function isCurrentVertPosition(VertPosition: integer): boolean;
      procedure handleCommand(commandValue: char);
      function getNewVertPosition(commandValue:char):integer;
      //function getNewPosition(commandValue: char): integer;
    protected
      moveUpChar: char;
      moveDownChar: char;
      Vertposition: integer;
  end;

  Scene = class // Сцена Анимации
    public
      procedure handleCommand();
      procedure run(AnimalItem: D1Animal; SecondAnimal: D2Animal);
      procedure drawSceneFrame(AnimalItem: D1Animal; SecondAnimal: D2Animal);
      function getCommand(): char;
    protected
      command: char; // последняя введенная команда
      function getMax(a, b: integer): integer;
  end;

// -- Реализация Scene -------

procedure Scene.run(AnimalItem: D1Animal; SecondAnimal: D2Animal);
begin
  // обработки событий
  while(self.getCommand() <> 'q') do
  begin
    ClrScr();
    // новый метод, для отрисовки кадра и всех объектов
    self.drawSceneFrame(AnimalItem, SecondAnimal);
    writeln();
    Delay(50);
    if (keyPressed()) then
    begin
       self.handleCommand();
       AnimalItem.handleCommand(self.getCommand());
       SecondAnimal.handleCommand(self.getCommand());
    end;
  end;

  writeln('Scena zavershena!');
end;

// Отрисовка кадра сцены
procedure Scene.drawSceneFrame(AnimalItem: D1Animal; SecondAnimal: D2Animal);
var maxPosition, i,j: integer;
begin
   maxPosition :=
     self.getMax(AnimalItem.getPosition(), SecondAnimal.getPosition());
   for j:=1 to SecondAnimal.getVertPosition() do
     if (SecondAnimal.isCurrentVertPosition(j)) or (j=1) then
       for i:=1 to maxPosition do
       begin
         if (AnimalItem.isCurrentPosition(i)) OR (SecondAnimal.isCurrentPosition(i)) then
         begin
           if (AnimalItem.isCurrentPosition(i)) and (j=1) then
             AnimalItem.drawFrame();
           if (SecondAnimal.isCurrentPosition(i)) and (SecondAnimal.isCurrentVertPosition(j)) then
             SecondAnimal.drawFrame();
         end else
           write(' ');
       end;
     writeln();
end;

function Scene.getMax(a, b: integer): integer;
begin
  if (a > b) then
    result := a
  else
    result := b;
end;

procedure Scene.handleCommand();
begin
  self.command := ReadKey(); // читаем символ из консоли
end;

function Scene.getCommand(): char;
begin
  result := self.command;
end;



// -- Реализация Animal -------
constructor Animal.create(skinValue, moveLeftChar, moveRightChar: char);
begin
  self.skin := skinValue;
  self.moveLeftChar := moveLeftChar;
  self.moveRightChar := moveRightChar;
  self.command := ' ';  // значение по умолчанию
  self.position := 1;
end;

procedure Animal.drawFrame();
begin
  write(self.skin);
end;

// больше не работаем с консолью напрямую
procedure Animal.handleCommand(commandValue: char);
begin
  self.position := self.getNewPosition(commandValue);
end;

function Animal.getNewPosition(commandValue: char): integer;
begin
  result := self.position; // предыдущее значение, как значение по умолчанию
  if (commandValue = self.moveRightChar) then
    result := self.position + 1
  else
    if ((commandValue = self.moveLeftChar) AND (self.position > 1)) then
      result := self.position - 1;
end;

function Animal.getCommand(): char;
begin
  result := self.command;
end;

function Animal.getPosition(): integer;
begin
  result := self.position;
end;

function Animal.isCurrentPosition(position: integer): boolean;
begin
  result := (position = self.position);
end;

//D1Animal
constructor D1Animal.create(skinValue, moveLeftChar, moveRightChar: char);
begin
  Inherited create(skinValue, moveLeftChar, moveRightChar);
  self.Vertposition := 1;
end;

//D2Animal
constructor D2Animal.create(skinValue, moveleftChar, moveRightChar: char);
begin
  Inherited create(skinValue, moveLeftChar, moveRightChar);
  self.moveUpChar := 'u';
  self.moveDownChar := 'd';
  self.Vertposition := 1;
end;

procedure D2Animal.handleCommand(commandValue: char);
begin
  //if(commandValue = 'l')or(commandValue = 'r') then
  self.position := self.getNewPosition(commandValue);
  //else if (commandValue = 'u')or(commandValue = 'd') then
  self.VertPosition:= self.getNewVertPosition(commandValue);
end;

function D2Animal.getNewVertPosition(commandValue: char): integer;
begin
  result := self.Vertposition;
  if (commandValue = self.moveDownChar) then
    result := self.Vertposition + 1
  else
    if ((commandValue = self.moveUpChar) AND (self.Vertposition > 1)) then
      result := self.Vertposition - 1;
end;

function D2Animal.getVertPosition():integer;
begin
  result:=self.VertPosition;
end;

function D2Animal.isCurrentVertPosition(VertPosition: integer): boolean;
begin
  result := (Vertposition = self.Vertposition);
end;

// ---------------
var
  AnimalItem: D1Animal; // первое животное
  Dog: D2Animal;       // второе животное
  SceneItem: Scene;
begin
  AnimalItem := D1Animal.create('*', '1', '2');
  Dog := D2Animal.create('@', 'l', 'r');
  SceneItem :=  Scene.create(); // создаем сцену
  SceneItem.run(AnimalItem, Dog); // запускаем анимацию

  readln();
end.                              
vedro-compota's picture

Добавил разбор с возможными вариантами решения этой проблемы: https://fkn.ktu10.com/?q=node/17229

_____________
матфак вгу и остальная классика =)