Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Правильно я понимаю наследование типов данных в лиспе?

Я где-то читал в pcl или еще где о наследовании типов данных в лиспе, помоему оно похоже на Java только не все есть object. Может кто помнит или знает, какие типы данных есть в лиспе и как они наследуются???
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
          ---> Cons Cell ---> NIL
         /
        / 
       /
OBJECT 
       \                        /---> T
        \            ---> Symbol|---> Var
         \          /           \---> Function
          ---> Atom  
                    \           /---> INT
                     ---> Number|---> FLOAT
                                |---> COMPLEX
                                \---> RATIO 
Ответ: Catstail, Я вот планирую сделать вот так, но вот думаю как лучше будет

Lisp
1
2
3
4
5
Object{:type typeof() toString()}
ConsCell{:car :cdr} extends Object
Atom{:name :data} extends Object
T = Atom{"T", true}
NIL = Atom{enum{"NIL", "`()"}, ConsCell{NULL, NIL}} 
Вопрос: Наследование и Композиция

Много раз слышал о том, что Композиция почти всегда лучше Наследования. Так вот у меня такой вопрос -- Как же узнать ту самую ситуацию, когда Наследование предпочтительнее?
Ответ:
Сообщение от Razor23Donetsk
Много раз слышал о том, что Композиция почти всегда лучше Наследования
Тут есть два аспекта. Теоретический и технический.

Теоретически, наследование и композиция - совсем разные случаи.
Наследование отображает связь вида "является" (например джип является автомобилем).
Композиция это связи вида "состоит из" (например автомобиль состоит из кузова и колес).
И тут никакого "композиция лучше наследования" быть не может. Вы не можете сказать что джип состоит из автомобиля (и понтов ).

НО. Реальность несколько сложнее теоретического ООП. Поэтому на практике иногда можно заменить наследование композицей. Это делается тогда, когда изначально невозможно определить тип объекта, либо объект может менять свой класс, от которого он унаследован.
Простой пример:
Есть класс Person и от него унаследовано два класса Student и Professor.
Далее у нас есть студент Вася Пупкин. Поскольку он студент, то естественно мы для него создаем класс Student. Все хорошо, до тех пор пока Вася студент. Но наступает момент, когда Вася идет в армию заканчивает институт и становится профессором. Возникает вопрос, а что же делать с объектом класса Student? Ведь изменить тип объекта после того, как он создан уже нельзя. Получается нужно уничтожать объект Student, создавать объект Professor и копировать туда данные про Васю. Но это неудобно. К тому же Вася уже будучи профессором может снова поступить в ВУЗ и стать одноврменно и студентом и так далее.
Для разрешения таких случаев, можно сделать следующим образом:
Васю сделать типа Person. А типы Student и Professor не наследовать от Person, а хранить в виде списка внутри Person (то есть сделать композицию).
И тогда, пока Вася студент - внутри его Person будет храниться Student, как только закончит ВУЗ - Student из списка можно удалить. При этом пересоздавать объект Person - не нужно, что гораздо удобнее.
Вопрос: Наследование. Переопределение виртуальной функции

Здравствуйте. Нужно создать классы, наследование. Переопределить для каждого класса виртуальную функцию Print. К каждому классу добавить +поле.
Выводится ерунда.

Прикрепляю файл.
Наследование от:
Продукт -> Товар: Цветы и Торт (тоже наследование, от товара).

Мб кто-то видит ошибки? Спасибо.
 Комментарий модератора zss
П.5.18.Правил
Запрещено размещать задания и решения в виде картинок и других файлов с их текстом.
Ответ: Типы полей какие должны быть? a и b у Товара - это что? Если это числа, то используй другой целый тип или приводи к нему при выводе, иначе они будут интерпретироваться как символы.
А здесь что?
Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        Product Pro(10, 20);
    Tovar Tov(20, 30, 100);
    Zweti Zwe(100, 5);
    Tort Tor(5, 10.09);
 
 
    Product P, *pP = &P;
    Tovar T, *tT = &T;
    Zweti Z, *zZ = &Z;
    Tort Tr, *Tt = &Tr;
    pP ->Print();
    tT ->Print();
    zZ ->Print();
    Tt ->Print();
Во-первых, зачем понадобились указатели? Во-вторых, P, T, Z, Tr инициализируются конструкторами по умолчанию, которые у тебя ничего не делают, и поля будут содержать мусор.
Вот так примерно должно быть:
Код C++
1
2
3
4
5
6
7
8
    Product Pro('a', 'b');
    Tovar Tov(20, 30, 100);
    Zweti Zwe(100, 5);
    Tort Tor(5, 10.09); // 10.09 - это что? Там целый тип
    Pro.Print();
    Tov.Print();
    Zwe.Print();
    Tor.Print();
Вопрос: Проблема с полями объекта при наследовании

Парочка вопросов. Использую Microsoft Visual Studio 2015.
1)Как сделать так, чтобы в консоль во всех случаях выводилось значение переменной var?
Если убрать определение поля "double x = 999" в классе SameText (оно не нужно, так как поле наследуется) то возникнет ошибка "Error C2385 ambiguous access of 'x'".
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
     
    ///ABSTRCAT LIBRARY/////////////////////
    #define abstract
    abstract class Sprite{
    public:
        double x = 999;
        virtual void setX(double x)=0;
    };
    abstract class Text:public Sprite{
    public:
        virtual void setText(char* text)=0;
    };
    ///IMPLEMENTATION///////////////////////
    class SameSprite:public Sprite{
    public:
        void setX(double x){
            this->x = x;
        }
    };
    class SameText: public Text, public SameSprite{
    public:
        double x = 999;
        void setX(double x){
            this->x = x;
        }
        void setText(char* text){}
    };
    int main(){
        Sprite* sprite;
        Text* text;
        SameSprite* same;
        ///
        double var = 3;
        SameText* sameText = new SameText();
        sprite = (Sprite*)((SameSprite*)sameText);
        text = (Text*)sameText;
        same = (SameSprite*)sameText;
        same->x = var;
        cout<<sprite->x<<"\n";//3
        cout<<text->x<<"\n";//999
        cout<<same->x<<"\n";//3
        cout<<sameText->x<<"\n";//999
        system("PAUSE");
        return 0;
    }
Можно 42-ю строчку заменить на "sameText->x = var;", по сути ничего не измениться, только в этот раз будет возвращено только одно значение 3, вместо двух.

Вообще, даже если не рассматривать множественное наследование, я заметил странное поведение C++: если в классах-наслениках определять поля, которые присутствуют в базовых классах, тогда эти поля себя ведут просто как переменные с доступом через указатель на объект. Ведь базовый класс может быть абстрактным, экземпляр которого нельзя создавать, но его поле будет все равно доступно и иметь свои значения, как-будто экземпляр этого абстрактного класса создан. Вот пример, для наглядности. Здесь показано поведение при переопределении наследуемого поля и без этого (нормальное поведение). Хотя указатель типа базового абстрактного класса Sprite (sprite) и указывает на объект класса SameSprite (same), наследуемого от Sprite, это не мешает выражениям 'same->x' и 'sprite->x' возвращать те значения, которые им присвоены (разные), хотя объекта sprite в принципе не может существовать, значит и не должно выделятся память для хранения второго значения поля x, но мы видим обратное.
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
     
    using namespace std;
    #define Message(s) MessageBox(0,s,"",0)
     
    #define abstract
    abstract class Sprite{
    public:
        double x = 999;
        virtual void setX(double x)=0;
    };
    class SameSprite:public Sprite{
    public:
        double x = 999;
        void setX(double x){
            this->x = x;
        }
    };
    class SameSprite2:public Sprite{
    public:
        void setX(double x){
            this->x = x;
        }
    };
    class SubSameSprite2:public SameSprite2{
    public:
        void setX(double x){
            this->x = x;
        }
    };
    int main(){
        Sprite* sprite;
        SameSprite* same = new SameSprite();
        SameSprite2* same2 = new SameSprite2();
        SubSameSprite2* subSame2 = new SubSameSprite2();
        sprite = same;
        sprite->x=1;
        cout<<same->x<<"\n";//999
        cout<<sprite->x<<"\n";//1
        cout<<"\\\\\\\n";
        sprite = same2;
        sprite->x=2;
        cout<<same2->x<<"\n";//2
        cout<<sprite->x<<"\n";//2
        cout<<"\\\\\\\n";
        sprite = subSame2;
        sprite->x = 4;
        cout<<same2->x<<"\n";//2
        cout<<subSame2->x<<"\n";//4
        cout<<sprite->x<<"\n";//4
        ///
        cout<<"Static objects test\n";
        SameSprite sameStatic;
        Sprite& spriteStatic = sameStatic;
        spriteStatic.x = 1;
        cout<<sameStatic.x<<"\n";//999
        cout<<spriteStatic.x<<"\n\\\\\\\n";//1
        system("PAUSE");
        return 0;
    }

В полностью ООП языках, например в Java, попросту нельзя определять поля в наследниках, присутствующие в базовых классах, иначе возникает ошибка при компиляции. Поэтому попутно возникает еще один вопрос. 2) Это фича языка, или это особенность конкретной реализации, баг?
Сообщение отредактировано: riden -
Ответ:
Цитата VisualProg @
2. Вы намеренно путаете самого себя, и неоднозначно определяете имена переменных.
Кстати вот ещё. Почему-то апологеты противности множественного наследования забывают, что конфликт идентификаторов возникает при любом случайном их совпадении, а не только при наследовании, а если нет конфликта, то нет и неоднозначности. Это в дополнение к прошлому моему тезису о склонности множественного наследования быть сложным.
Вопрос: Наследование свойств и методов классов в Delphi

Не могу решить проблему с наследованием свойств и методов.
Задача: Разработать консольное приложение, содержащее класс TPoint следующей структуры: поля – координаты точки; методы: Area – функция для вычисления площади, Show – процедура для отображения результатов, Move – процедура смещения. На базе класса TPoint создать класс-потомок TRectangle с полями – длиной и высотой прямоугольника. Создать по одному экземпляру каждого класса.
Проблема в том, что у меня не наследуются ни поля ни функции ни процедуры. Что только не делал, наследование не выходит. Постоянно какие-нибудь да ошибки есть. Искал в инете, нигде не нашел как точно осуществить наследование. Может плохо искал... Подскажите пожалуйста как решить...

Код Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
program Project2;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,
  Windows;
 
type
  TPoint=class
    x, y: real;
    constructor Create;
    destructor Destroy; override;
    function Area: real; virtual; abstract;
    procedure Move;
    procedure Show;
  end;
  TRectangle=class(TPoint)
    a, b: real;
    constructor CreateA;
    destructor Destroy; override;
    function Area: real;
  end;
 
constructor TPoint.Create;
begin
  Writeln('Введите координаты точки');
  Write('x='); Readln(x);
  Write('y='); Readln(y);
end;
 
constructor TRectangle.CreateA;
begin
  Writeln('Введите стороны прямоугольника');
  Write('a='); Readln(a);
  Write('b='); Readln(b);
end;
 
destructor TPoint.Destroy;
begin
  inherited Destroy;
end;
 
destructor TRectangle.Destroy;
begin
  inherited Destroy;
end;
 
function TRectangle.Area;
begin
  result:=a*b;
end;
 
procedure TPoint.Move;
var dx, dy: real;
begin
  Writeln('Введите смещения dx и dy:');
  Write('dx='); Readln(dx);
  Write('dy='); Readln(dy);
  x:=dx+x; y:=dy+y;
end;
 
procedure TPoint.Show;
begin
  Writeln('Координаты точки: x=', x,' y=', y);
end;
 
procedure TRectangle.Move;
var dx, dy: real;
begin
  Writeln('Введите смещения dx и dy:');
  Write('dx='); Readln(dx);
  Write('dy='); Readln(dy);
  x:=dx+x; y:=dy+y;
end;
 
procedure TRectangle.Show;
var x1, y1: real;
begin
  x1:=x+b; y1:=y+b;
  Writeln('(',x:3:1,',',y1:3:1,')------------(',x1:3:1,',',y1:3:1,')');
  Writeln('    |                    |    ');
  Writeln('    |                    |    ');
  Writeln('    |                    |    ');
  Writeln('(',x:3:1,',',y:3:1,')------------(',x1:3:1,',',y:3:1,')');
  Writeln;
  Writeln('ÏëîùГ*äü: ', Area:3:1);
  Writeln;
end;
 
var Rc: TRectangle;
    Pt: TPoint;
begin
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
 
  Pt:=TPoint.Create;
  Rc:=TRectangle.CreateA;
  Pt.Show;
  Rc.Show;
  Writeln('Смещенные точка и прямоугольник');
  Pt.Move;
  Rc.Move;
  Pt.Show;
  Rc.Show;
  Readln;
end.
Ответ: оффтоп, но
не является хорошей идеей делать у класса метод типа Show
инкапусляция - это как раз когда класс общается с внешним миром посредством невизуальных вещей
что-то принять, как-то обработать, вернуть строку с результатом, это да
взаимодействовать с экраном - точно нет
в данном приложении это еще куда ни шло, но в более практических вещах это приведет к нехорошим последствиям в плане архитектуры приложения
Вопрос: Проблема с наследованным типом.

Привет.

Мне нужно написать сервис по существующей WSDL.

Обнаружилась весьма неприятная организация - после того, как обрабатываю WSDL через ScvUtil, создаются, вроде бы, нормальные контракты.

НО, когда я строю на этих контрактах свой сервис, а затем пытаюсь написать тестового клиента (да и вообще, просто подключаюсь через WcfTestClient) - не подцепляется информация о типе.

Важно примечание - не подцепляется информация о наследовании.

Вот код,к оторый сгенерил ScvUtil, и на котором я запускаю службу

[System.Diagnostics.DebuggerStepThroughAttribute()]
[MessageContract(IsWrapped = true, WrapperName = "GetMyInfo",
                   WrapperNamespace = "http://MyInfo.ru/goods")]
public partial class GetMyInfo : MessageRoot {
}


[System.Diagnostics.DebuggerStepThroughAttribute()]
[MessageContract(IsWrapped = true, WrapperName = "MessageRoot",
                   WrapperNamespace = "http://MyInfo.ru/goods")]
public partial class MessageRoot {


А вот код, который создает тестовый клиент, при импортировании службы:

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ServiceModel.MessageContractAttribute(WrapperName="GetMyInfo", 
						  WrapperNamespace="http://MyInfo.ru/goods", 
						  IsWrapped=true)]
    public partial class GetMyInfo {
        
        public GetMyInfo () {
        }
    }


нету никакой ссылки на тип MessageRoot !! А по сути, в нем все поля и хранятся.

Подскажите пожалуйста в чем может быть дело.
Ответ: Странно еще то, что Scvutil сам не создает эти KnowType. Т.е. он импортнул типы, создал ИЕРАРХИЮ наследования (разобрался же) - но атрибуты поставить не удосужился.
Вопрос: Мне нужно справиться с ошибкой при наследовании в Java. Нужен ваш совет

Сделал один проект с наследованием, там все хорошо. Вот он:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package myfitrstprogram;                                    // Пакет и название пакета, в котором нахолится программа
 
 
import testobject.Asus;
import testobject.Computer;
import testobject.Notebook;
import testobject.Toshiba;
 
 
public class MyFitrstProgram {                              // Это я создал публичный класс прежче чем написать код
 
 
    public static void main(String[] args) { 
//        Computer comp1 = new Computer("IBM", 2048, 350, 3, 2.4);       // comp это ссылчный элемент
//        Computer comp2 = new Computer(17.2, 160000, 3, 3.2);
      
          
        
    
//            comp1.setName("IBM");         // Модель компьютера
//            comp1.setRam(2048);              // Объем ОП
//            comp1.setHdd(350);               // Объем жесткого диска
//            comp1.setWeight(3);              // Вес
//            comp1.setProcessor(2.4);         // Процессор
//            comp1.setSize_monitor(17.4);     // Размер монитора
//            comp1.setColor(170000);          // Кол-во цветов
//            comp1.setUsb(4);                 // Кол-во USB
            
 
//            comp2.setName("Apple");
//            comp2.setRam(512);
//            comp2.setSize_monitor(15.0);
//            comp2.setColor(160000);
//            comp2.setUsb(3);
//            comp2.setHdd(1024);
//            comp2.setProcessor(3.2);
 
            
        
     
//        comp1.on();
//        comp1.load();
//        comp1.off();
//        
//        comp2.on();
//        comp2.load();
//        comp2.off();
 
        
                    
        
        Notebook notebook = new Notebook();
        
            notebook.setName("MacBook pro");
            
        
          notebook.on();
          notebook.load();
          notebook.off();
          
          
        Toshiba toshiba = new Toshiba() {};
        
            toshiba.setName("Toshiba");
            toshiba.setDvd("Да");
            
          
         toshiba.on();
         toshiba.load();
         toshiba.off();
         
        
        Asus asus = new Asus() {};
        
            asus.setName("Asus");
            asus.setDvd("Нет");
            
         
         asus.on();
         asus.load();
         asus.off();
             
         
    }
  
}
 
 
 
// Computer comp = null; Это означает, что объект Computer (comp - это ссылочный эелемент) ни на что не ссылается и подвержен удалению;
// new Computer(); создалась переменная типа Computer;
// Computer comp2 = new Computer(); Переменная comp2 ссылается на созданный объект Computer
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package testobject;                 // Создание сначала пакет, далее название пакета java
 
 
public class Computer {             // Создание класса далее название класса java
    
 
    String name;            // public модификатор доступа. Название должно быть текстовым по этому пишем String далее имя "name"
    
    int ram;                // Кол-во опреративной памяти обозначается в цифрах. По-этому пишем "int"
    
    int hdd;                // Кол-во памяти в hdd обозначается в цифрах. По-этому пишем "int"
    
    double weight;          // Вес с плавающей точкой double. Вес обозначается Weight
    
    double processor;       // Частота  процессора
    
    double size_monitor;    // Размер монитора
    
    int color;              // кол-во цветов
    
    int usb;                // кол-во usb портов
    
    
    
    public Computer() {
        System.out.println("Computer: Конструктор");
        
    }
 
    public Computer(String name, int ram, int hdd, double weight, double processor) {
        this.name = name;
        this.ram = ram;
        this.hdd = hdd;
        this.weight = weight;
        this.processor = processor;
    }
 
    public Computer(double size_monitor, int color, int usb, double processor) {
        this.size_monitor = size_monitor;
        this.color = color;
        this.usb = usb;
        this.processor = processor;
 
    }
    
    
    
    
    
    public int getUsb() {
        return usb;
    }
    
    public void setUsb(int newUsb) {
        if (newUsb<0){
            System.out.println("Данное значение "+newUsb+" не может быть отрицательным");
        }else if(newUsb>4){
            System.out.println("Данное значение "+newUsb+" не может быть больше 4");
 
        }      
    }
    
    public int getColor() {
        return color;
    }
    
    public void setColor(int newColor) {
        if(newColor>0){
        }else{
            System.out.println("Данное значение "+newColor+" не может быть отрицательным");
        }
    }
    
    
    public double getSize_monitor() {
            return size_monitor;
    }
    
    public void setSize_monitor(double newSize_monitor) {
            if (newSize_monitor>0){
            size_monitor = newSize_monitor;
            }else{
                System.out.println("Данное знаечение "+newSize_monitor+" не может быть отрицательным");
            }
    }
    
   public double getProcessor() {
            return processor;       
    }
    
    public void setProcessor(double newProcessor) {
            if (newProcessor>0){
           }else{
                System.out.println("Это значение "+newProcessor+" не может быть отрицательным");
           }
    }
    
    public int getWeight() {
        return color;
    }
    
    public void setWeight(int newWeight) {
        if(newWeight>0){
        }else{
            System.out.println("Данное значение "+newWeight+" не может быть отрицательным");
        }
    }
    
    public String getName() {
            return name;
        }
    
    public void setName(String newName) {
            name = newName;
        }
    
    public int getRam() {
            return ram;
    }
    
    public void setRam(int newRam) {
            if (newRam>0){
                ram = newRam;
            }else{
                System.out.println("Переданное значение "+newRam+" не может быть отрицательным!");
            }
    }
    
    public int getHdd() {
            return hdd;
    }
    
    public void setHdd(int newHdd) {
            if (newHdd>0){
                hdd = newHdd;
            }else{
                System.out.println("Переданное значение "+newHdd+" не может быть отрицательным!");
            }
    }
    
    
    
    
    
    
    public void on() {                                   // void - это тип метода т.е будет ли он возвращать какое-то значание или не будет. Написал, что пока не будет не чего возвращить и по этому написал "void". Мы создали одно дейсвие для компьтера "on" 
        print("Я включился. Моя модель "+getName());    // Вывод текста + имя компьтера
    }
    
    public void off() { 
        print("Я выключился");
    }
    
    public void load() {
        print("Я загружаюсь. Мой объем жесткого диска: "+getHdd()+" Гб. Процессор Intel i7 с частотой: "+getProcessor()+" Ггц. Размер монитора: "+getSize_monitor()+" дюйм");
    }
 
    
    
    protected void print(String str) {
        System.out.println(str);
    }
     
    
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package testobject;
 
public class Notebook extends Computer {
    private String dvd;
 
    
    
    public Notebook(){
        System.out.println("Notebook: Конструктор");
    }
    
    
    @Override
    public String getName() {
            return name;
        }
    
    @Override
    public void setName(String newName) {
            name = newName;
        }
    
    public String getDvd() {
        return dvd;
    }
   
    public void setDvd(String newDvd) {
        dvd = newDvd;
    }
    
    @Override
     public void on() {   
         super.on();
        print("Notebook: я включился. Моя модель " +getName());    // Вывод текста + имя компьтера
    }
 
    @Override
     public void load() {
         
     }
     
     
}
Тоже самое создаю в новом проекте и мне почему-то выдает

Вот код этого проекта с ошибкой и почему компилятор выдает ошибку?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package printer;
 
import testobject.Hp;
 
public class Printer {
 
 
    public static void main(String[] args) {
 
//        Hp comp = new Hp("Hewlett-Packard", "ctx", 4600, "Laser");
        
//            comp.setName("Hewlett-Packard");
//            comp.setModel("ctx");
//            comp.setSeria(4600);
//            comp.setType("Laser");
            
//                comp.on();
//                comp.load();
//                comp.off();
 
                      
                    
                        
 
                    
                        
                    
    }
    
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package testobject;
 
 
public class Hp {
    
 
    String name;
    String model;
    int seria;
    String type;
 
    public Hp(String name, String model, int seria, String type) {
        this.name = name;
        this.model = model;
        this.seria = seria;
        this.type = type;
    }
 
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    
    
    public String getModel() {
        return model;
    }
    
    public void setModel(String model) {
        this.model = model;
    }
  
  
  
  
    public int getSeria() {
        return seria;
    }
    
    public void setSeria(int newSeria) {
        if(newSeria>0){
        }else{
            System.out.println("Данное значение не может быть отрицательным");
    }
        }
    
    
    
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
 
 
 
  
 
 
 public void on(){
     System.out.print(" Я включился. Моё название "+getName()+ " Моя модель " +getModel()+ " Моя серия " +getSeria()+ " Мой тип печати "+getType());
 }       
   
 public void load(){
     System.out.print(" Я загружаюсь. Моё название "+getName());
 }
  
 public void off(){
     System.out.print(" Я выключился. Моё название "+getName());
 }
    
 protected void print(String str) {
        System.out.println(str);
    }
    
}
Java
1
2
3
4
5
package testobject;
 
public class WifiRouter extends Hp {
    
}
Ответ: Computer: Конструктор // вызывается конструктор Hp
Я включился. Моё название null Моя модель null Моя серия 0 Мой тип печати null Я загружаюсь. Моё название null Я выключился. Моё название null

Все работает...
Вопрос: Используя наследование, создать класс для обработки баз данных двух типов

Есть задание по полиморфизму:
Используя свойство наследования создать класс для обработки баз данных двух типов. Создать по классу для каждой из БД. Долю общей функциональности обеих БД поместить в базовый класс, а два других класса сделать его производными. У каждого класса должен быть реализован собственный конструктор, независимый от базового класса. Ход программы отобразить комментариями.
Помогите пожалуйста, я вообще не понимаю, как это сделать. Зарание спасибо.
Ответ:
Сообщение от sawbosh
вообще не понимаю, как это сделать
Что-то типа того, ятд.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SQLite;
 
namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            DbHelper dbHelper = DbFactory.CreateHelper("CONNECT_STR", "Sql");
        }
    }
    public static class DbFactory {
        public static DbHelper CreateHelper(string connectStr, string dbType) {
            DbHelper dbHelper = null;
            if (dbType == "Sql") {
                dbHelper = new SqlDbHelper(connectStr);
            }
            else if (dbType=="SQLITE") {
                dbHelper = new SQLiteDbHelper(connectStr);
            }
            return dbHelper;
        }
    }
    public class SqlDbHelper : DbHelper {
        public SqlDbHelper(string connect_str)
            : base(connect_str) {
        }
 
        protected override User[] GetUsers() {
            throw new NotImplementedException();
        }
 
        protected override void InsertUser(string name, int age) {
            throw new NotImplementedException();
        }
 
        protected override void DeleteUser(int id) {
            throw new NotImplementedException();
        }
    }
    public class SQLiteDbHelper : DbHelper {
        public SQLiteDbHelper(string connect_str)
            : base(connect_str) {
        }
        protected override User[] GetUsers() {
            throw new NotImplementedException();
        }
 
        protected override void InsertUser(string name, int age) {
            throw new NotImplementedException();
        }
 
        protected override void DeleteUser(int id) {
            throw new NotImplementedException();
        }
    }
    public abstract class DbHelper {
        protected string CONNECT_STR;
        public DbHelper(string connect_str) {
            CONNECT_STR = connect_str;
        }
        protected abstract User[] GetUsers();
        protected abstract void InsertUser(string name, int age);
        protected abstract void DeleteUser(int id);
    }
    public class User {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}
Вопрос: Наследование в шаблонных типах

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template<typename T>
class B {
protected:
    T obj;
};
 
template<typename T>
class A : public B<T> {
public:
    T& data() {return obj;}
};
 
class D {
protected:
    int obj;
};
 
class C : public D {
public:
    int& data() {return obj;}
};
 
int main() {
    A<int> a;
    a.data();  // ошибка obj отсутствует в скопе.
 
    C c;
    c.data(); // ошибки нет, компилируется.
}
В чем разница между шаблонным и нешаблонным наследованием и как правильно расшарить область видимости предка?
Ответ:
Сообщение от Mirmik
В чем разница между шаблонным и нешаблонным наследованием и как правильно расшарить область видимости предка?
в том, что один и тот же шаблон в зависимости от своих формальных параметров,
может инстанцироваться в классы,
которые могут различаться как небо и земля.

по этой причине, до момента нстанцирования,
тобишь на момент парсинга собственно шаблона,
компилятор ещё понятия не имеет,
чем будет на самом деле базовый класс.

и то том, что таком будет какое то неведомое obj
Сообщение от Mirmik
C++
1
T& data() {return obj;}
компилятор не знает.
он же не телепат.

если программист считает, что какая то неведомая фигня
все таки будет, то он должен сообщить об этом явно.

например, так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template<typename T>
class B {
protected:
    T obj;
};
 
template<typename T>
class A : public B<T> {
public:
    // компилятор, obj - собственность класса
    T& data() {return this->obj;}
};
 
class D {
protected:
    int obj;
};
 
class C : public D {
public:
    int& data() {return obj;}
};
 
int main() {
    A<int> a;
    a.data();  
 
    C c;
    c.data(); 
}
хотите знать больше?

Вопрос: ООП. Перегрузка операторов в наследование с примесью полиморфизма

Здравствуйте, нужна помощь, а то мозг болит.

В общем не получается получить сумму разных атрибутов из разных наследуемых классов, а полиморфизм и наследование обязательны. Думал перегрузка поможет, не помогла - "TypeError: __add__() takes 1 positional argument but 2 were given".

Можно ли такое делать в Python и как (спрашиваю, потому, что задание для C# и там скорее всего можно, наверное), желательно показать на моем коде(если его так можно назвать)?

И лично вопрос не совсем по теме: стоит ли учить C# для ООП или плевать и продолжать на Питончике, просто я пробовал C# раньше и для меня лично (мое ИМХО) он показался муторным, а особенно для новичка, а вот Питонище до меня доносит суть, что скажете?


Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from abc import ABCMeta, abstractmethod, abstractproperty
 
 
class Clothes:
    __metaclass__=ABCMeta
    clothes = 'одежда '
    resultV = 0
    resultH = 0
    def __init__(self, V, H):
        self.Vv = V
        self.new_V()
        self.Hh = H
        self.new_H()
    @abstractmethod
    def new_V(self):
        pass
    @abstractmethod
    def new_H(self):
        pass
    @abstractmethod
    def __add__(self):
        print(self.clothes, 'V', self.resultV)
        print(self.clothes, 'H',self.resultH)
    #def resultHa(self):
        
        
class Coat(Clothes):
    resultV = 0
    def __init__(self, V):
        self.Vv = V
        self.new_V()
    def new_V(self):
        self.resultV = round(self.Vv/6.5 + 0.5, 2)        
    def __add__(self):
        return self.resultV
        
class Suit(Clothes):
    resultH = 0
    def __init__(self, H):
        self.Hh = H
        self.new_H()
    def new_H(self):
        self.resultH = round(2*self.Hh+0.3, 2)
    def __add__(self):
        return self.resultH
 
 
 
spisokCo = list(range(6))
spisokSu = list(range(6))
 
 
spisokCo[0] = Coat(43)
spisokCo[1] = Coat(51)
spisokCo[2] = Coat(42)
spisokCo[3] = Coat(56)
spisokCo[4] = Coat(23)
spisokCo[5] = Coat(56)
 
spisokSu[0] = Suit(52)
spisokSu[1] = Suit(41)
spisokSu[2] = Suit(55)
spisokSu[3] = Suit(12)
spisokSu[4] = Suit(21)
spisokSu[5] = Suit(32)
 
 
a = 0
b = 0
for element in spisokCo:
    print(spisokCo[a] + spisokSu[b])
    a += 1
    b += 1
Ответ: __py__,
какой-то безграмотный этот Ваш лутц. То что он по Вашей ссылке называет "перегрузкой операторов", типа __init__, __str__, к ней вообще отношения не имеет. Перегрузка -- это, вообще, термин из статики, но уж если и притягивать его сюда за уши, то в контексте диспетчеризации по типам аргументов, а то что он там рассказывает, к этому вообще отношения не имеет.