面向对象编程基础
1.基础概论
面向对象三大特征:继承、封装、多态
2.简单的类和对象
案例:创建Led类
案例01:感受构造函数与析构函数的功能
class Led {public :Led(); //构造函数声明,初始化对象,在创建对象的时候自动执行~Led();//析构函数。清除对象,在对象清除前自动执行
};
Led:: Led(){//构造函数
Serial.println("Led Object Created");
pinMode (2,OUTPUT);
}Led::~Led(){加粗样式Serial.println("Led Object Deleted");}
void setup() {Serial.begin(9600);Led myLed;//创建一个Led对象,与创建变量类似Serial.println("Hellow, this is function of setup");}void loop() {}
案例02:感受类的设计与应用
class Led {public : //公共:可以通过类创建对象,然后通过对象调用。
// private : 私有,只能在类内部调用,不能通过对象调用。
//构造函数与析构函数,属于特殊函数,不能被对象调用,而是在对象创新与消失时自动执行。Led(); //声明构造函数,对象一旦创建就会调用构造函数~Led();//声明细析函数。在对象被删除前执行void on();//声明成员函数(功能函数),函数功能:点亮Led灯void off();//声明成员函数(功能函数),函数功能:熄灭Led灯};
Led:: Led() { //构造函数Serial.println("Led Object Created");pinMode (2, OUTPUT);
}Led::~Led() {Serial.println("Led Object Deleted");
}void Led:: on() {digitalWrite(2, HIGH);Serial.println("Led is on");
}
void Led:: off() {digitalWrite(2, LOW);Serial.println("Led is off");
}void setup() {Serial.begin(9600);Led myLed;//创建一个Led对象,与创建变量类似Serial.println("Hellow, this is function of setup");myLed.on();//调用Led类中的on函数delay(1000);myLed.off();//调用Led类中的off函数delay(1000);
}void loop() {}
案例03 多构造函数理解
class Led {public : //公共:可以通过类创建对象,然后通过对象调用。// private : 私有,只能在类内部调用,不能通过对象调用。//构造函数与析构函数,属于特殊函数,不能被对象调用,而是在对象创新与消失时自动执行。Led(); //声明构造函数,对象一旦创建就会调用构造函数Led(int uesrLedPin);~Led();//声明细析函数。在对象被删除前执行void on();//声明成员函数(功能函数),函数功能:点亮Led灯void off();//声明成员函数(功能函数),函数功能:熄灭Led灯int ledPin = 2;//默认ledPin等于2,即创建对象没有参数输入时,默认控制2号引脚};
Led:: Led() { //构造函数Serial.println("Led Object Created");pinMode (ledPin, OUTPUT);
}
//Led::Led(int uesrLedPin):ledPin(uesrLedPin){//该语句表示参数传递,功能与ledPin = uesrLedPin相同
Led::Led(int uesrLedPin) {Serial.println("Led Object Created");ledPin = uesrLedPin;//参数传递pinMode(ledPin, OUTPUT);
}Led::~Led() {Serial.println("Led Object Deleted");
}void Led:: on() {digitalWrite( ledPin , HIGH);Serial.println("Led is on");
}
void Led:: off() {digitalWrite( ledPin , LOW);Serial.println("Led is off");
}void setup() {Serial.begin(9600);Led myLed;//创建一个Led对象,与创建变量类似Led myLed2(7);Serial.println("Hellow, this is function of setup");myLed.on();//调用Led类中的on函数myLed2.on();//调用Led类中的on函数delay(1000);myLed.off();//调用Led类中的off函数myLed2.off();delay(1000);
}void loop() {}
3.类的封装
将类的设计制与使用者分离,将类中重要的成员通过private 修饰封装起来,不允许对象随意调用,然后在类的共有成员内部设置get 函数和set函数,通过get函数和set函数访问private修饰的私有成员。然后再通过对象调用get和set函数来访问私有成员。
案例3.1封装后
class Led {public : //公共成员:可以通过类创建对象,然后通过对象调用。// private : 私有,只能在类内部调用,不能通过对象调用。//构造函数与析构函数,属于特殊函数,不能被对象调用,而是在对象创新与消失时自动执行。Led(); //声明构造函数,对象一旦创建就会调用构造函数Led(int uesrLedPin);~Led();//声明细析函数。在对象被删除前执行void on();//声明成员函数(功能函数),函数功能:点亮Led灯void off();//声明成员函数(功能函数),函数功能:熄灭Led灯int getLedPin();//封装接口,通过该函数获得私有成员void setLedPin(int userLed);//封装接口,通过该函数修改私有成员private ://私有成员:只能在类内部调用int ledPin = 2;
};
Led:: Led() { //构造函数Serial.println("Led Object Created");pinMode (ledPin, OUTPUT);
}
//Led::Led(int uesrLedPin):ledPin( ){//该语句表示参数传递,功能与ledPin = uesrLedPin相同
Led::Led(int uesrLedPin) {Serial.println("Led Object Created");ledPin = uesrLedPin;//参数传递pinMode(ledPin, OUTPUT);
}Led::~Led() {Serial.println("Led Object Deleted");
}void Led :: on() {digitalWrite( ledPin , HIGH);Serial.println("Led is on");
}
void Led :: off() {digitalWrite( ledPin , LOW);Serial.println("Led is off");
}
int Led :: getLedPin(){return ledPin;}void Led :: setLedPin(int userLedPin){ledPin = userLedPin;pinMode(ledPin,OUTPUT);}
void setup() {Serial.begin(9600);Led myLed;//创建一个Led对象,与创建变量类似myLed.setLedPin(3);//通过接口改变私有变量ledPinint myLedPin = myLed.getLedPin();//通过接口改变私有变量ledPinSerial.print("myLedPin=");Serial.println(myLedPin);/*int myLedPin2 = myLed.ledPin;tg */
}void loop() {}
4.类的分文件管理
4.1 新建 .h文件
输入Led.h,点击’'好“,然后Ctrl+S保存。Led.h文件保存类的声明部分。
/*存放类的声明*/
#ifndef _LED_H_ //理解为if not define ,即如果 _LED_H_没有被定义则执行下面的语句直到endif为止,用于保证类程序只被编译一次。
#define _LED_H_#include <Arduino.h>
class Led {public : //公共成员:可以通过类创建对象,然后通过对象调用。// private : 私有,只能在类内部调用,不能通过对象调用。//构造函数与析构函数,属于特殊函数,不能被对象调用,而是在对象创新与消失时自动执行。Led(); //声明构造函数,对象一旦创建就会调用构造函数Led(int uesrLedPin);~Led();//声明细析函数。在对象被删除前执行void on();//声明成员函数(功能函数),函数功能:点亮Led灯void off();//声明成员函数(功能函数),函数功能:熄灭Led灯int getLedPin();void setLedPin(int userLed);private ://私有成员:只能在类内部调用int ledPin = 2;
};
#endif
#ifdef与#ifndef详解
#ifdef与#ifndef语句起始于#ifdef与#ifndef,终于#endif。
#define DEBUG
void setup() {Serial.begin(9600);
#ifdef DEBUG // 可以理解为if define
//如果DEBUG被宏定义了,则执行以下语句直到#endifSerial.println("DEBUG Defined");
#endif#ifndef DEBUG// 可以理解为if not define
//如果DEBUG没有被宏定义了,则执行以下语句直到#endifSerial.println("DEBUG NOT Defined");
#endif
}
void loop() {
}
4.2 .cpp文件
重复上面步骤新建一个窗口
Led.cpp存放类的成员部分。
/*存放类的具体成员*/#include "Led.h"
Led:: Led() { //构造函数Serial.println("Led Object Created");pinMode (ledPin, OUTPUT);
}
//Led::Led(int uesrLedPin):ledPin(uesrLedPin){//该语句表示参数传递,功能与ledPin = uesrLedPin相同
Led::Led(int uesrLedPin) {Serial.println("Led Object Created");ledPin = uesrLedPin;//参数传递pinMode(ledPin, OUTPUT);
}Led::~Led() {Serial.println("Led Object Deleted");
}void Led :: on() {digitalWrite( ledPin , HIGH);Serial.println("Led is on");
}
void Led :: off() {digitalWrite( ledPin , LOW);Serial.println("Led is off");
}
int Led :: getLedPin(){return ledPin;}void Led :: setLedPin(int userLedPin){ledPin = userLedPin;pinMode(ledPin,OUTPUT);}
5 继承
类的声明 .h文件
/*存放类的声明*/
#ifndef _LED_H_ //理解为if not define ,即如果 _LED_H_没有被定义则执行下面的语句直到endif为止
#define _LED_H_#include <Arduino.h>
class Led {public : //公共成员:可以通过类创建对象,然后通过对象调用,可以被继承。// private : 私有,只能在类内部调用,不能通过对象调用。//构造函数与析构函数,属于特殊函数,不能被对象调用,而是在对象创新与消失时自动执行。Led(); //声明构造函数,对象一旦创建就会调用构造函数Led(int uesrLedPin);~Led();//声明细析函数。在对象被删除前执行void on();//声明成员函数(功能函数),函数功能:点亮Led灯void off();//声明成员函数(功能函数),函数功能:熄灭Led灯int getLedPin();void setLedPin(int userLed);private : //私有成员:只能在类内部调用,不能被继承int ledPin = 2;
};
/***************继承*************//public:可以被对象调用,可以继承,可以在类内部调用//protected:不能被对象调用,可以继承,可以在类内部调用//private:不能被对象调用,不能被继承,只能在类内部调用//class pwmLed :private :Led{//将父类公共成员继承来作为自己的私有成员//class pwmLed :protected :Led{//将父类公共成员继承来作为自己的半公共成员,可以被子类继承,但不能被对象调用。
****/
class pwmLed : public Led { //将父类公共成员继承来作为自己的公共成员public:void on(int user_pwm_val);//函数重载:覆盖了父类的on()函数,on()函数将不能在子类中使用int get_pwm_val();//封装接口获取pwm的值private:int pwm_val = 0;};#endif
类成员。.cpp文件
/*存放类的具体成员*/#include "Led.h"
Led:: Led() { //构造函数Serial.println("Led Object Created");pinMode (ledPin, OUTPUT);
}
//Led::Led(int uesrLedPin):ledPin(uesrLedPin){//该语句表示参数传递,功能与ledPin = uesrLedPin相同
Led::Led(int uesrLedPin) {Serial.println("Led Object Created");ledPin = uesrLedPin;//参数传递pinMode(ledPin, OUTPUT);
}Led::~Led() {Serial.println("Led Object Deleted");
}void Led :: on() {digitalWrite( ledPin , HIGH);Serial.println("Led is on");
}
void Led :: off() {digitalWrite( ledPin , LOW);Serial.println("Led is off");
}
int Led :: getLedPin() {return ledPin;
}void Led :: setLedPin(int userLedPin) {ledPin = userLedPin;pinMode(ledPin, OUTPUT);
}void pwmLed:: on(int user_pwm_val) {pwm_val = user_pwm_val;analogWrite(getLedPin(), pwm_val);
}int pwmLed:: get_pwm_val() {return pwm_val;
}
对象创建于应用
# include "Led.h"pwmLed myPwmLed;
void setup() {Serial.begin(9600);myPwmLed.setLedPin(3);int myPwmLedPin = myPwmLed.getLedPin();Serial.print("myPwmLedPin =");Serial.println(myPwmLedPin );}void loop() {for(int i=0;i<255;i++){myPwmLed.on(i);Serial.print("myPwmLed.get_pwm_val()in =");Serial.println(myPwmLed.get_pwm_val() ); delay(10);}}
6Arduino库的建立。
0.新建两个案例程序
1.arduino程序文件打开文件夹并新建example文件夹
2.在examples文件夹下新建与案例同名的文件夹并在文件夹下设计案例程序。
3.新建关键字高亮文本文件txt并命名为keywords.txt并保存在库文件夹下
# 井号为注释,解释说明
#class (KEYWORD1) 关键词1 即颜色1 高亮类名
Led KEYWORD1
pwmLed KEYWORD1#function and method (KEYWORD2) 关键词2 即颜色2 高亮类的成员(或方法)
on KEYWORD2
off KEYWORD2
getLedPin KEYWORD2
setLedPin KEYWORD2
4.压缩库文件为zip格式
5.重启arduino_IED,在项目中加载库,选择添加zip库,找到刚才的压缩文件直到IDE下方显示 :库已经添加,请检查”导入库“菜单
表示库文件添加成功