day44——面向对象特征

2024-08-29 21:20
文章标签 特征 面向对象 day44

本文主要是介绍day44——面向对象特征,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、封装

1.1 面向对象的三大特质

封装、继承、多态,如果问有四大特征,可以外加一个抽象

封装:将实现同一事物的所有的属性(成员变量)和行为(成员函数)封装到一个整体,我们称之为类(class)。类对外部信息有一个屏障作用。

1.2 C++中的类(class)

C++中的类,是由C++中的结构体演化而来的,只需要将struct改成关键字class,就定义了一个类

C++中类和结构体的区别:默认的权限不同,结构体中默认权限为public,类中默认权限为private

默认的继承方式不同,结构体的默认继承方式为public,类的默认继承方式为private

1.3 定义格式

class 类名
{public:功能的成员属性、函数protected:受保护的成员属性、函数private:私有的成员属性、函数
};

1> 类中的成员属性和成员函数分为不同的权限

public:该权限下的成员,可以在类内、子类中、类外被访问

protected:该权限下的成员,可以在类内、子类中直接被访问,类外不允许被访问

private:该权限下的成员,只能在类内被访问,子类、类外不允许被访问

2> 如果没有指定权限,则默认为私有权限

3> 一个类中,访问权限可以出现多次,也可以出现在任意地方,一般情况下,我们将同一权限下的成员写到一个关键字下面

4> 一个访问权限的范围,是从当前关键字开始到下一个关键字或者整个类的定义结束为止

5> 一般情况下,成员属性定义成私有的,成员函数定义成公有的

6> 类的访问权限是针对于类体而言的,不是针对于类对象的

#include <iostream>using namespace std;//将实现人的所有属性和行为都封装到一个整体,
//后期如果需要一个人,只需要使用该类实例化对象后,通过对象为整个程序服务
class Person
{string skill = "C++";          //技能public:string name = "zhangsan";        //姓名    功能的属性protected:int pwd = 123456;           //银行卡密码private:int money = 1000000;         //私房钱public:void show(){cout<<"  name = "<<name<<endl;        //公共权限下的成员,类内可以直接访问cout<<"  pwd = "<<pwd<<endl;          //受保护权限下的成员,类内可以直接访问cout<<"  money = "<<money<<endl;      //私有成员,类内可以直接访问cout<<"  skill = "<<skill<<endl;      //默认为私有成员,类内可以直接访问}};/******************************************主程序***************************/
int main()
{Person p1;          //使用类定义变量的过程,称为实例化对象,p1就是Person类的一个对象//通过p1使用成员cout<<"name = "<<p1.name<<endl;          //公共权限下的成员,类外可以直接访问//cout<<"pwd = "<<p1.pwd<<endl;            //收保护成员,类外无法直接访问//cout<<"money = "<<p1.money<<endl;      //私有成员,类内可以直接访问,类外无法访问//cout<<"skill = "<<p1.skill<<endl;      //默认为私有成员,类内可以直接访问,类外无法访问p1.show();                                 //类中公共权限下的成员,类外可以直接访问return 0;
}

练习:

自定义一个矩形类,包含私有成员属性 高(height)和宽(width),

公共成员函数:初始化宽、高函数

设置宽度函数

设置高度函数

获取宽度函数

获取高度函数

求矩形的周长(Perimeter)函数

求矩形的面积(Area)函数

#include <iostream>using namespace std;
class rectangle
{
public:void init(int w, int h);       //初始化一个矩形bool set_width(int w);       //设置宽度bool set_height(int h);      //设置高度int get_width();          //获取宽度int get_height();          //获取高度int perimeter();           //获取周长int area();                 //获取面积
private:int width=0;             //矩形宽度int height=0;             //矩形高度
};
bool rectangle::set_width(int w)
{if(w<=0){cout<<"提供的宽度不合法"<<endl;return 0;}width=w;return 1;
}bool rectangle::set_height(int h)
{if(h<=0){cout<<"提供的高度不合法"<<endl;return 0;}height=h;return 1;
}int rectangle::get_width()
{return width;
}int rectangle::get_height()
{return height;
}int rectangle::perimeter()
{return 2*(height+width);
}int rectangle::area()
{return height*width;
}void rectangle::init(int w, int h)
{if(w<=0 || h<=0){cout<<"初始化失败"<<endl;}width = w;height = h;
}int main()
{//使用矩形类实例化一个矩形rectangle r1;            //实例化一个对象r1.init(3,5);          //初始化一个矩形cout<<r1.perimeter()<<endl;cout<<r1.area()<<endl;return 0;
}

练习:

在上面练习的基础上,写一个函数,可以比较两个矩形框是否相等

相等条件:宽==宽 高==高

#include <iostream>using namespace std;
class rectangle
{
public:void init(int w, int h);       //初始化一个矩形bool set_width(int w);       //设置宽度bool set_height(int h);      //设置高度int get_width();          //获取宽度int get_height();          //获取高度int perimeter();           //获取周长int area();                 //获取面积bool judge_rect(rectangle &r);        //定义判断两个矩形框是否相对
private:int width=0;             //矩形宽度int height=0;             //矩形高度
};
bool rectangle::set_width(int w)
{if(w<=0){cout<<"提供的宽度不合法"<<endl;return 0;}width=w;return 1;
}bool rectangle::set_height(int h)
{if(h<=0){cout<<"提供的高度不合法"<<endl;return 0;}height=h;return 1;
}int rectangle::get_width()
{return width;
}int rectangle::get_height()
{return height;
}int rectangle::perimeter()
{return 2*(height+width);
}int rectangle::area()
{return height*width;
}//判断两个矩形框是否相等,成员函数版
bool rectangle::judge_rect(rectangle &r)
{if(r.width==width && r.height==height){return true;}return false;
}void rectangle::init(int w, int h)
{if(w<=0 || h<=0){cout<<"初始化失败"<<endl;}width = w;height = h;
}//定义全局函数版本
bool judge_rect(rectangle &r1, rectangle &r2)
{//判断两个矩形是否相等if(r1.get_width()==r2.get_width() && r1.get_height()==r2.get_height()){return true;}return false;      //不相等
}int main()
{//使用矩形类实例化一个矩形rectangle r1;            //实例化一个对象r1.init(3,5);          //初始化一个矩形cout<<r1.perimeter()<<endl;cout<<r1.area()<<endl;//定义第二个矩形rectangle r2;r2.init(3,6);//if(judge_rect(r1, r2))if(r1.judge_rect(r2))            //r2.judge_rect(r1){cout<<"两个矩形框相等"<<endl;}else{cout<<"两个矩形框不相等"<<endl;}return 0;
}

1.4 分文件编译

1> 头文件

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include <iostream>using namespace std;//头文件中主要放:类的声明、全局函数的声明、全局变量的定义、类型重命名、宏定义
class rectangle
{
public:void init(int w, int h);       //初始化一个矩形bool set_width(int w);       //设置宽度bool set_height(int h);      //设置高度int get_width();          //获取宽度int get_height();          //获取高度int perimeter();           //获取周长int area();                 //获取面积bool judge_rect(rectangle &r);        //定义判断两个矩形框是否相对
private:int width=0;             //矩形宽度int height=0;             //矩形高度
};bool judge_rect(rectangle &r1, rectangle &r2);        //全局函数的声明#endif // RECTANGLE_H

2>源文件

#include"rectangle.h"bool rectangle::set_width(int w)
{if(w<=0){cout<<"提供的宽度不合法"<<endl;return 0;}width=w;return 1;
}bool rectangle::set_height(int h)
{if(h<=0){cout<<"提供的高度不合法"<<endl;return 0;}height=h;return 1;
}int rectangle::get_width()
{return width;
}int rectangle::get_height()
{return height;
}int rectangle::perimeter()
{return 2*(height+width);
}int rectangle::area()
{return height*width;
}//判断两个矩形框是否相等,成员函数版
bool rectangle::judge_rect(rectangle &r)
{if(r.width==width && r.height==height){return true;}return false;
}void rectangle::init(int w, int h)
{if(w<=0 || h<=0){cout<<"初始化失败"<<endl;}width = w;height = h;
}//定义全局函数版本
bool judge_rect(rectangle &r1, rectangle &r2)
{//判断两个矩形是否相等if(r1.get_width()==r2.get_width() && r1.get_height()==r2.get_height()){return true;}return false;      //不相等
}

3> 主程序

#include"rectangle.h"int main()
{//使用矩形类实例化一个矩形rectangle r1;            //实例化一个对象r1.init(3,5);          //初始化一个矩形cout<<r1.perimeter()<<endl;cout<<r1.area()<<endl;//定义第二个矩形rectangle r2;r2.init(3,6);//if(judge_rect(r1, r2))if(r1.judge_rect(r2))            //r2.judge_rect(r1){cout<<"两个矩形框相等"<<endl;}else{cout<<"两个矩形框不相等"<<endl;}return 0;
}

1.5 this指针

1> this的内含:是类的非静态成员函数所拥有的一个隐藏的形参指针,指代该对象本身起始地址,哪个对象使用我,我就表示哪个对象

2> this指针的格式:类名 * const this;

3> 对于this指针而言,如果没有显性使用该指针,仅仅只是使用成员,那也是默认使用了this指针

3> this指针的使用场景

场景1:当成员函数的形参名和成员变量同名时,可以使用this指针进行区分

场景2:在拷贝复制函数中,需要返回自身引用时,也必须使用this指针(后面讲)

#include <iostream>using namespace std;
class rectangle
{
public:void init(int width, int height);       //初始化一个矩形void show(){cout<<"width = "<<width<<"  height = "<<height<<endl;}
private:int width=0;             //矩形宽度int height=0;             //矩形高度
};void rectangle::init(int width, int height)
{if(width<=0 || height<=0){cout<<"初始化失败"<<endl;}this->width = width;             //可以通过this指针改变this所指向内存中的值this->height = height;cout<<"this = "<<this<<endl;//this = NULL;          //不能更改指针的指向}int main()
{//使用矩形类实例化一个矩形rectangle r1;            //实例化一个对象r1.init(3,5);          //初始化一个矩形cout<<"&r1 = "<<&r1<<endl;         //r1的地址r1.show();//在实例化一个对象rectangle r2;r2.init(2,2);cout<<"&r2 = "<<&r2<<endl;         //r2的地址return 0;
}

1.6 类的大小

1> 一个空的类的大小为1字节,用于占位使用,如果后期有成员变量的加入,则会将这一字节的空间分配出去

2> 类中的成员函数不占类的空间大小,但是成员属性会占用类的大小

3> 成员属性分配空间的大小遵循字节对齐原则

4> 如果类中有虚函数(后期讲),那么类中就会多一个虚指针的大小

5> 如果该类是虚继承(后期讲)自父类,那么该类中也会增加一个虚指针的大小

#include <iostream>using namespace std;class Temp
{
public:int num;      //整型成员变量void show(){cout<<"num = "<<num<<endl;}//类中有虚函数时,就会多分配一个虚指针的空间virtual void display(){cout<<"我是虚函数"<<endl;}virtual void display(int ){cout<<"我是虚函数"<<endl;}};int main()
{cout<<"sizeof(Temp) = "<<sizeof(Temp)<<endl;return 0;
}

二、类中特殊的成员函数(非常重要)

2.1 类中提供的特殊成员函数

1> 特殊的原因:如果用户不显性定义这些函数,系统也会自动提供这些函数,如果用户显性定义了这些函数,那么系统就不提供了。

无论这些特殊的成员函数,是系统提供的还是用户字节定义的,都无需用户手动调用,特殊的时机,系统会自动调用

2> 构造函数、析构函数、拷贝构造函数、拷贝复制函数、移动构造函数、移动复值函数、取地址运算符重载

2.2 构造函数

1> 功能:

使用类去实例化对象时,为对象进行资源的申请以及初始化使用的

2> 定义格式

1、构造函数没有返回值
2、函数名与类同名
3、访问权限,一般为public
4、 类名(形参列表){函数体内容}

3> 调用时机:

当使用类实例化对象时,系统自动调用,无需手动调用

1、栈区空间:使用类实例化对象时,系统自动调用

类名 变量名(实参); //此时就调用的构造函数

2、堆区空间:只有在使用new申请空间时,自动调用构造函数

类名 *指针名; //此时仅仅只是定义一个指针变量,并没有为对象分配空间

指针名 = new 类名(实参); //此时调用的构造函数

#include <iostream>using namespace std;class Stu
{
public:Stu(){cout<<"Stu的构造函数"<<endl;}
};int main()
{//在栈区申请对象空间Stu s1;//堆区空间申请对象Stu *ptr;          //此时不调用构造函数ptr = new Stu;      //此时调用构造函数return 0;
}

4> 构造函数分为有参构造和无参构造函数,有参构造函数可以为成员属性进行初始化,这些构造函数之间构成重载关系

5> 一个类中可以有多个构造函数,每个对象仅仅只会调用一个构造函数

6> 如果类中没有定义构造函数,那么,系统会自动提供一个无参构造函数,用于对对象空间的申请,如果程序员自己定义了构造函数,系统就不再提供那个无参构造了,如果还想使用无参构造,需要自己定义一个无参构造

#include <iostream>using namespace std;class Stu
{
private:string name;int age;double score;public://无参构造Stu(){cout<<"Stu的无参构造函数"<<endl;}//自定义有参构造Stu(string n, int a){this->name = n;this->age = a;cout<<"Stu::有参构造"<<endl;}void show(){cout<<"name = "<<name<<endl;cout<<"age = "<<age<<endl;cout<<"score = "<<score<<endl;}
};int main()
{//在栈区申请对象空间Stu s1;                       //此时调用了无参构造,只为对象申请了空间,但是没有为对象初始化s1.show();cout<<"**************************************"<<endl;//申请一个对象,调用有参构造Stu s2("zhangsan", 18);          //此时调用了有参构造s2.show();cout<<"**************************************"<<endl;//堆区空间申请对象Stu *ptr;          //此时不调用构造函数ptr = new Stu;      //此时调用构造函数return 0;
}

7> 构造函数初始化对象可以使用初始化列表完成

使用方式:类名(形参1,形参2,。。。形参n):成员1(形参1),成员2(形参2),。。。成员n(形参n)

{函数体内容}

说明:在构造函数的小括号后,由冒号引出初始化列表,括号外时成员变量,括号内是形参

#include <iostream>using namespace std;class Stu
{
private:string name;int age;double score;public://无参构造Stu(){cout<<"Stu的无参构造函数"<<endl;}//自定义有参构造Stu(string n, int a){this->name = n;         //对成员的赋值操作this->age = a;cout<<"Stu::有参构造1"<<endl;}//定义有参构造:使用初始化列表完成对成员的初始化工作Stu(string n, int a, double s):name(n),age(a),score(s){cout<<"Stu::有参构造2"<<endl;}void show(){cout<<"name = "<<name<<endl;cout<<"age = "<<age<<endl;cout<<"score = "<<score<<endl;}
};int main()
{//在栈区申请对象空间Stu s1;                       //此时调用了无参构造,只为对象申请了空间,但是没有为对象初始化s1.show();cout<<"**************************************"<<endl;//申请一个对象,调用有参构造Stu s2("zhangsan", 18);          //此时调用了有参构造s2.show();cout<<"**************************************"<<endl;//申请一个对象,调用有参构造Stu s3("lisi", 20, 99.8);s3.show();cout<<"**************************************"<<endl;//堆区空间申请对象Stu *ptr;          //此时不调用构造函数ptr = new Stu;      //此时调用构造函数return 0;
}

8> 必须使用初始化列表的情况

1、当构造函数的形参名和成员变量名同名时,可以使用初始化列表来解决

2、当类中有const修饰的成员变量时,对该变量也必须进行初始化,使用初始化列表解决

3、当类中有引用成员时,对该成员的操作也必须使用初始化列表完成

4、当类中有其他类的成员子对象时,对该成员的操作也必须使用初始化列表完成,如果没有使用初始化列表调用有参构造,则系统会自动调用成员子对象的无参构造

#include <iostream>using namespace std;class Toy
{
public:Toy() {cout<<"Toy::无参构造"<<endl;}Toy(string n):name(n) {cout<<"Toy::有参构造"<<endl;}private:string name;};class Stu
{
private:string name;int age;double score;const int value;        //类中有const类型的成员int &key;             //类中有引用成员Toy t;               //类中有其他类的成员子对象public://无参构造Stu():value(1314), key(*(new int(520))), t("hello kity"){cout<<"Stu的无参构造函数"<<endl;}//自定义有参构造Stu(string n, int a, int &k):value(1314), key(k){this->name = n;         //对成员的赋值操作this->age = a;cout<<"Stu::有参构造1"<<endl;}//定义有参构造:使用初始化列表完成对成员的初始化工作Stu(string name, int age, double score, int &k):name(name),age(age),score(score),value(1314),key(k){cout<<"Stu::有参构造2"<<endl;}void show(){cout<<"name = "<<name<<endl;cout<<"age = "<<age<<endl;cout<<"score = "<<score<<endl;}
};int main()
{//在栈区申请对象空间Stu s1;                       //此时调用了无参构造,只为对象申请了空间,但是没有为对象初始化s1.show();cout<<"**************************************"<<endl;//堆区空间申请对象Stu *ptr;          //此时不调用构造函数ptr = new Stu;      //此时调用构造函数return 0;
}

2.3 析构函数

1> 功能:在对象消亡时,用于给对象回收空间使用的

2> 定义格式

1、没有返回值
2、函数名:类名前加个波浪线  ~类名
3、权限:一般为public
4、没有参数,所以,一个类中只有一个析构函数,不能进行重载
5、格式:   ~类名()

3> 调用时机:当对象的生命周期结束后,用于回收内存空间

栈区:当栈空间释放后,系统会自动调用该类的析构函数

堆区:当使用delete关键字释放对象空间时,系统自动调用

4> 如果没有手动定义析构函数,系统会提供一个析构函数,用于回收类对象的空间,如果手动定义了析构函数,那么,系统就不再提供默认的析构函数了。

#include <iostream>using namespace std;class Toy
{
public:Toy() {cout<<"Toy::无参构造"<<endl;}Toy(string n):name(n) {cout<<"Toy::有参构造"<<endl;}private:string name;};class Stu
{
private:string name;int age;double score;const int value;        //类中有const类型的成员int &key;             //类中有引用成员Toy t;               //类中有其他类的成员子对象int *ptr;         //指针成员public://无参构造Stu():value(1314), key(*(new int(520))), t("hello kity"), ptr(new int(666)){cout<<"Stu的无参构造函数"<<endl;}//自定义有参构造Stu(string n, int a, int &k):value(1314), key(k){this->name = n;         //对成员的赋值操作this->age = a;cout<<"Stu::有参构造1"<<endl;}//定义有参构造:使用初始化列表完成对成员的初始化工作Stu(string name, int age, double score, int &k):name(name),age(age),score(score),value(1314),key(k){cout<<"Stu::有参构造2"<<endl;}void show(){cout<<"name = "<<name<<endl;cout<<"age = "<<age<<endl;cout<<"score = "<<score<<endl;}//定义析构函数~Stu(){delete ptr;          //释放指针的空间cout<<"STU::析构函数"<<endl;}
};int main()
{//在栈区申请对象空间Stu s1;                       //此时调用了无参构造,只为对象申请了空间,但是没有为对象初始化s1.show();cout<<"**************************************"<<endl;//堆区空间申请对象Stu *ptr;          //此时不调用构造函数ptr = new Stu;      //此时调用构造函数//释放ptr的空间delete ptr;       //此时会调用析构函数return 0;
}

作业

仿照string类,实现myString

#include <iostream>
#include <cstring>class myString
{
private:char *str;          //记录c风格的字符串int size;            //记录字符串的实际长度public://无参构造myString():size(10){str = new char[size];         //构造出一个长度为10的字符串str[0] = '\0';                // 初始化为空字符串}//有参构造myString(const char *s){size = strlen(s);             // 计算传入字符串的长度str = new char[size + 1];     // 分配足够的内存空间,加1是为了存储结束符'\0'strcpy(str, s);               // 复制传入的字符串到新分配的内存空间}//判空函数bool empty() const{return str[0] == '\0';}//size函数int length() const{return size;}//c_str函数const char* c_str() const{return str;}//at函数char at(int index) const{if (index >= 0 && index < size){return str[index];}else{throw std::out_of_range("Index out of range");}}//二倍扩容void doubleCapacity(){int newSize = size * 2;char *newStr = new char[newSize + 1]; // 分配新的内存空间,加1是为了存储结束符'\0'strcpy(newStr, str);                  // 复制原字符串到新内存空间delete[] str;                          // 释放原内存空间str = newStr;                          // 更新指针指向新的内存空间size = newSize;                        // 更新字符串长度}
};int main()
{myString s1;myString s2("Hello, world!");std::cout << "s1 is " << (s1.empty() ? "empty" : "not empty") << std::endl;std::cout << "s2 is " << (s2.empty() ? "empty" : "not empty") << std::endl;std::cout << "Length of s1: " << s1.length() << std::endl;std::cout << "Length of s2: " << s2.length() << std::endl;std::cout << "s2 content: " << s2.c_str() << std::endl;std::cout << "Character at index 7 in s2: " << s2.at(7) << std::endl;return 0;
}

这篇关于day44——面向对象特征的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118922

相关文章

OmniGlue论文详解(特征匹配)

OmniGlue论文详解(特征匹配) 摘要1. 引言2. 相关工作2.1. 广义局部特征匹配2.2. 稀疏可学习匹配2.3. 半稠密可学习匹配2.4. 与其他图像表示匹配 3. OmniGlue3.1. 模型概述3.2. OmniGlue 细节3.2.1. 特征提取3.2.2. 利用DINOv2构建图形。3.2.3. 信息传播与新的指导3.2.4. 匹配层和损失函数3.2.5. 与Super

ffmpeg面向对象-待定

1.常用对象 rtsp拉流第一步都是avformat_open_input,其入参可以看下怎么用: AVFormatContext *fmt_ctx = NULL;result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); 其中fmt_ctx 如何分配内存的?如下 int avformat_open_input(

《计算机视觉工程师养成计划》 ·数字图像处理·数字图像处理特征·概述~

1 定义         从哲学角度看:特征是从事物当中抽象出来用于区别其他类别事物的属性集合,图像特征则是从图像中抽取出来用于区别其他类别图像的属性集合。         从获取方式看:图像特征是通过对图像进行测量或借助算法计算得到的一组表达特性集合的向量。 2 认识         有些特征是视觉直观感受到的自然特征,例如亮度、边缘轮廓、纹理、色彩等。         有些特征需要通

chapter06 面向对象基础 知识点Note

文章目录 前言类的设计 属性和行为对象的内存解析 (堆 栈 方法区)类的成员之一 变量(属性) field类的成员之二 方法 method对象数组方法重载 overload可变个数的形参 语法糖方法的值传递机制递归关键字package importMVC设计模式import导入面向对象特征之一 封装类的成员之三 构造器JavaBeanUML类图 前言 ` 面向对象封装 面向

HalconDotNet中的图像特征与提取详解

文章目录 简介一、边缘特征提取二、角点特征提取三、区域特征提取四、纹理特征提取五、形状特征提取 简介   图像特征提取是图像处理中的一个重要步骤,用于从图像中提取有意义的特征,以便进行进一步的分析和处理。HalconDotNet提供了多种图像特征提取方法,每种方法都有其特定的应用场景和优缺点。 一、边缘特征提取   边缘特征提取是图像处理中最基本的特征提取方法之一,通过检

【JVM】JVM栈帧中的动态链接 与 Java的面向对象特性--多态

栈帧 每一次方法调用都会有一个对应的栈帧被压入栈(虚拟机栈)中,每一个方法调用结束后,都会有一个栈帧被弹出。 每个栈帧中包括:局部变量表、操作数栈、动态链接、方法返回地址。 JavaGuide:Java内存区域详解(重点) 动态链接 动态链接:指向运行时常量池中该栈帧所属方法的引用。 多态 多态允许不同类的对象对同一消息做出响应,但表现出不同的行为(即方法的多样性)。 多态

WebShell流量特征检测_哥斯拉篇

90后用菜刀,95后用蚁剑,00后用冰蝎和哥斯拉,以phpshell连接为例,本文主要是对后三款经典的webshell管理工具进行流量分析和检测。 什么是一句话木马? 1、定义 顾名思义就是执行恶意指令的木马,通过技术手段上传到指定服务器并可以正常访问,将我们需要服务器执行的命令上传并执行 2、特点 短小精悍,功能强大,隐蔽性非常好 3、举例 php一句话木马用php语言编写的,运行

java基础总结15-面向对象11(抽象类)

下面通过一下的小程序深入理解抽象类 因此在类Animal里面只需要定义这个enjoy()方法就可以了,使用abstract关键字把enjoy()方法定义成一个抽象方法,定义如下:public abstract void enjoy();   从某种意义上来说,抽象方法就是被用来重写的,所以在父类声明的抽象方法一定要在子类里面重写。如果真的不想在子类里面重写这个方法,那么可以再在子类里

java基础总结14-面向对象10(多态)

面向对象最核心的机制——动态绑定,也叫多态 1 通过下面的例子理解动态绑定,即多态 package javastudy.summary;class Animal {/*** 声明一个私有的成员变量name。*/private String name;/*** 在Animal类自定义的构造方法* @param name*/Animal(String name) {this.name = n

java基础总结13-面向对象9(对象转型)

对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型。转型的意思是:如把float类型转成int类型,把double类型转成float类型,把long类型转成int类型,这些都叫转型。把一种形式转成另外一种形式就叫转型。除了基础数据类型的转型之外(基础数据类型的转型:大的可以转成小的,小的也可以转成大的。),对象领域里面也有对象之