类的继承/方法的重写/与C++的比较day11

在描述“人”的信息时,通常少了有“性别”的信息表示,那么在类设计中,如何设计性别表示?

1、 用字符串,”男”,”女”

2、 用布尔类型的数据true/false表示

3、 双例类

4、 枚举


Rectangle.java作为Shape类的直接子类,因为属于继承关系,所以子类继承了父类的两个方法,即求面积和周长的方法。父类没有办法计算面积和周长,但子类因为是具体的形状,可以计算真正意义上的面积和周长。

在子类中,对于继承来的方法,根据子类本身的需要,将方法中的代码进行改写,称为“重写override”。

子类对于父类中成员的继承,是没有任何选择,即“全盘继承”,不是有选择的继承;

利用父类型的引用来操纵子类对象,就可以调用子类中重写的方法;

要点在于:通过父类型引用调用的方法,都是在父类型中定义的;

父类中的四种访问级别的成员:private<default<protected<public

子类会全部继承下来,但是对于继承来的成员,有的子类可以访问,有的不能访问。这里的可以访问是指,在类外可以看作是子类的成员;所谓不可访问,就是父类中特有访问成员,在类外来看,不能做为子类的成员;

is-a”关系,子类对象是父类对象。凡是父类对象出现的地方,都可以用子类对象代替,因为子类功能强于父类。

小学教师

中学教师

大学教师

将子类对象赋给父类的引用;可以理解为:把子类对象当父类对象用;

永远不需要任何转换。

反之,是否可以?即父类对象能否赋给子类的引用?

在特定的情况下,也可以。即将父类对象赋给子类的引用!

条件是:父类对象实际上是子类对象。

 

继承链中子类对从父类中继承来方法的重写:

当父引用指向的实际对象是子类对象时,才能安全转换:

运算符:instanceof,这个双目运算符,即“谁是谁的实例(对象)”

boolean b = s1 instanceof Rectangle;

运算符的左边,是一个对象s1,右边是个类名,此表达式是用来判断s1是否是Rectangle的一个实例,如果是,返回真,否则返回假。

 

java继承中的“单根类”机制:

Java中所有的类都是一个类的直接子类间接子类

Object

所有的类都继承这个根类;

如果一个顶层类没有显式提供父类,就默认继承了Object类,是它的直接子类;如果显式提供了父类,则是Object类的间接子类;


类的继承少不了“重写”,或者说类的继承就是为了重写。

三点:

1、 继承父类中设计的字段及对字段的setterGetter操作,

2、 添加新的字段,

3、 重写继承来的方法(不是必须的)

也有特殊的情况,子类继承父类中定义的方法,不需要重写,但在不同的子类中会有不同的功能。

在类继承链上重写时,在一个子类中,只有一个方法存在;

 

在父类中定义方法,在子类中根据自身的需要重新实现;

不同的子类在实现从父类中定义的同一个方法时,会有不同的代码实现,即是同一个方法,有多种实现;同一个消息,有多种形态。称为面向对象的“多态”机制。

java中,“多态”机制是通过什么方式实现的?子类方法的重写!

封装、继承和多态的特性最早出现在C++中,与Java两者相比:

1、 封装部分基本上相同;

2、 继承区别较大:

a) C++中没有根类,类之间除了继承关系外,各自为政;Java中则有根类,可以将所有构造类型统一到Object中;

b) C++支持多继承,Java只支持单继承;

c) C++在继承时,有私有、公有、保护性继承,相当复杂,而Java则大大简化了继承方式,只支持单继承中的公有继承;

d) C++中生成类对象时,可以将对象分配在栈区,也可以分配在堆区;而Java则大大简化了生成对象的操作,只在堆区存放对象;

e) C++中设计的类,如果字段成员中有指针存在,则必须要在类中定义析构方法来释放内存;在Java中,即使字段中有引用,也不需要手动释放,由垃圾回收机制解决;

f) 在C++的继承中,分为静态关联和动态关联两种形式。所谓静态关联,就是在编译器在编译时,就清楚地知道引用的是哪个对象;而动态关联,与Java中类似,只有在运行时,才知道引用指向的是哪个对象;C++中支持静态和动态两种类型的调用,而Java只支持动态调用;

g) 对于类中的一些特定方法,settergetter方法在两种语言中基本类似。对于对象的输出,在C++中用“运算符重载”功能解决,而在Java中,用重写toString()方法解决;在C++中有析构方法,Java中没有。

h) C++中如果没有提供访问修饰级别,则默认为私有,而Java中则为default访问级别。

上可得出如下结论:在C++中,既可以将对象存放到栈区域,也可以通过运算符new在堆区内存存放对象,一旦用new申请内存,就必须用delete释放;

静态关联与动态关联:

由上可知,当父子两个类对象aabb都保存在栈区时,调用相同的方法,并没有多态情况出现;这种方式属于“静态关联”。

使用C++中的动态关联才能出现多态。使用“引用”或“指针”。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中,可以通过继承 `fstream`,然后重写 `write`、`read` 和 `seek` 方法来实现自定义的文件读写操作。具体实现如下: ```c++ #include <fstream> #include <iostream> using namespace std; class MyFileStream : public fstream { public: MyFileStream(const char* filename, ios::openmode mode) : fstream(filename, mode) {} void write(const char* buf, streamsize size) { // 自定义写入操作,这里只是简单地输出写入的内容 cout << "Writing " << size << " bytes: "; for (streamsize i = 0; i < size; ++i) { cout << buf[i]; } cout << endl; // 调用父类的写入方法 fstream::write(buf, size); } void read(char* buf, streamsize size) { // 自定义读取操作,这里只是简单地输出读取的内容 cout << "Reading " << size << " bytes" << endl; // 调用父类的读取方法 fstream::read(buf, size); } streampos seek(streamoff off, ios_base::seekdir dir) { // 自定义偏移操作,这里只是简单地输出偏移量和方向 cout << "Seeking " << off << " bytes " << (dir == ios::beg ? "from the beginning" : (dir == ios::cur ? "from the current position" : "from the end")) << endl; // 调用父类的偏移方法 return fstream::seek(off, dir); } }; int main() { MyFileStream fs("test.txt", ios::out | ios::in | ios::trunc); fs.write("Hello, world!", 13); char buf[13]; fs.seekg(0); fs.read(buf, 13); cout << "Read: " << buf << endl; fs.close(); return 0; } ``` 在上面的示例中,我们定义了一个 `MyFileStream` 继承了 `fstream` ,并重写了 `write`、`read` 和 `seek` 方法。在 `write` 方法中,我们自定义了写入操作,输出了写入的内容,并调用了父类的写入方法;在 `read` 方法中,我们自定义了读取操作,输出了读取的内容,并调用了父类的读取方法;在 `seek` 方法中,我们自定义了偏移操作,输出了偏移量和方向,并调用了父类的偏移方法。 最后,在 `main` 函数中,我们创建了一个 `MyFileStream` 对象,并进行了写入、读取和偏移操作,输出了相应的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值