当前位置: 首页 > news >正文

15 dart类(get,set,静态,继承,抽象,接口,混入)

1.get与set方法

上节提到过,通过在属性前加上“_”,可以将其设置为私有属性,那么如果要在其他文件访问私有属性,那么该怎么办呢?这里就要用到get方法

get方法可以获得私有属性的值,而set方法则是对私有属性的值进行设定或者修改,在下面的代码中,由于一开始只是建立了属性mass,所以这里是属于设定。

//10 demo.dart文件
class Product {String ? name;double ? _mass ;double ? price;Product(this.name, this._mass, this.price) {print("商品名称:${this.name},重量:${this._mass}kg,价格:${this.price}元");}Product.say(a){print("我们这个产品很好,今天还打了${a}折");}double get mass{return _mass ?? 0;}set mass(double value){print("设置质量大小为:$value");this._mass = value;}}

这里要注意的是,要声明类型,如这里,声明的就是double类型,如果类型不一样或者不声明类型,大概率会因为类型不一致而会报错 

import "10 demo.dart";
void main(){Product p1 = Product("苹果", 0.5, 10);Product.say(8);p1.mass = 12;
}

然后再另外一个文件里面调用刚刚的文件,此时,便可以调用私有属性了,这就是get和set的妙用

2.静态属性和静态方法

我们知道,想要调用类里面的方法,我们需要先创建一个对象,然后通过对象来调用方法,但是有时候我们希望不用创建对象,就可以调用方法,这个时候,静态方法就出现了。

class Person {static var name = "张三";int age = 20;var sex = "男";static var work = "程序员";static void say(){print("大家好,我叫${name},我是一个${work}");}void say1(){print("我今年${age}岁了,我是${sex}的,我喜欢${work}");}
}void main(){Person p1 = Person();p1.say1();Person.say(); //静态方法调用不需要实例化对象
}

 对于静态属性与静态方法,可以直接调用,而无需实例化对象,当然,无需不是不能,所以你当然可以选择通过对象调用,但是注意,对于没有静态的属性,是不可以在静态方法里调用的,不然会报错,比如在上面的say方法中,调用age,那么就会报错。

3.继承

//父类
class Person {var name = "张三";int age = 20;var sex = "男";var work = "程序员";void say1(){print("我今年${age}岁了,我是${sex}的,我喜欢当${work}");}
}//子类
class Superperson extends Person{String skill1 = "飞行";String skill2 = "复活";void skillout(){print("看招,第一技能:${skill1}!");}void skillout2(){print("看招,第二技能:${skill2}!");}@override //重写父类的方法,必须加上@overridevoid say1(){ //重写父类的方法,必须加上@overrideprint("我是${name},我今年${age}岁了,我是${sex}的,我喜欢当${work},我的第一技能是${skill1},第二技能是${skill2}");}
}void main(){Person p1 = Person();p1.say1();Person p2 = Superperson(); //多态p2.say1();
}

父类即原来的类,而子类则是由父类得到的类,其中extends关键字是用于声明继承关系。子类可以拥有自己的方法,但是这里值得注意的是,如果要在子类中对父类的方法进行重写,请务必在前面添加@override,这样你才可以对父类的方法进行重写,不然会报错。

或许有人会想,如果在子类中,能否调用刚刚学的静态方法,实际上,由于静态方法只属于类本身,所以子类是不能继承的,如果调用,那么结果会是报错。接下来,我们展示下构造函数与继承的碰撞:

class Person {var name = "张三";int age = 20;var sex = "男";String ? work;Person(this.work){print("我是一个${work}");}void say1(){print("我今年${age}岁了,我是${sex}的,我喜欢当${work}");}
}//子类
class Superperson extends Person{String skill1 = "飞行";String skill2 = "复活";String ? bigskill;Superperson(bigskill):super("超级英雄"){ //super()调用父类的构造函数,必须放在第一行this.bigskill = bigskill;}void skillout(){print("看招,第一技能:${skill1}!");}void skillout2(){print("看招,第二技能:${skill2}!");}void skillout3(){print("看招,我的大招:${bigskill}!");}@override //重写父类的方法,必须加上@overridevoid say1(){ //重写父类的方法,必须加上@overrideprint("我是${name},我今年${age}岁了,我是${sex}的,我喜欢当${work}");}
}void main(){Superperson p2 = Superperson("寂灭"); //多态p2.say1();p2.skillout();p2.skillout2();p2.skillout3();
}

这里要注意的点,首先在继承父类的构造函数时,一定要用super关键字,然后super后面的括号传入的实参,取决于父类的属性那边有几个是存在空安全符的,像这里,父类那边只有一个work是带上此符号的,所以在super后面只用传入一个值。而super前面的括号,则看子类有多少个是存在空安全符,这里也是一个,所以也只要传入一个值,最后就是注意,子类继承父类构造函数的格式。

4.抽象类与抽象方法

有些时候,我们可能想创建一个概念上的类,它不该被实例化,而是仅仅作为一个模板,那么我们可以称之为抽象类。

抽象方法则是存在于类之中,抽象方法没有大括号,但是在子类中必须实现。

abstract class Level0{String ? name;int ? num;//抽象类的构造函数,子类必须实现Level0(this.name, this.num);
//抽象方法,子类必须实现sound0(who,where);
//抽象类也可以有普通方法time(specfic){print("当前楼层:${num},楼层名称:${name},时间是${specfic}");}
}class Level1 extends Level0{String ? skill1;Level1(name,num,skill1):super(name,num){this.skill1 = skill1;}sound0(who,where){print("${who}在${where}听到了声音");}
}class Level2 extends Level1{String ? skill2;Level2(name,num,skill1,skill2):super(name,num,skill1){this.skill2 = skill2;}@overridesound0(who,where){print("${who}在${where}听到了声音,${who}感到害怕,于是${who}使用了${skill2}成功离开");}
}void main(){Level1 l1 = Level1("起始之地",1,"飞行");l1.sound0("小明","1楼");l1.time("早上8点");print("在${l1.name}不慎跌入Level2");Level2 l2 = Level2("未知的沙滩",2,"飞行","绝对极速");l2.sound0("小明","2楼");l2.time("早上9点");
}

上方是一个两次继承,第一次是Level1继承了抽象类Level0,也是要重点关注的地方。

首先,我们看到Level0,会发现Level0有的方法没有大括号,有的有,这就是抽象类的特殊之处,抽象方法,可以没有大括号,但是后续继承的时候一定要补上。而在后面的Level1中,我们可以看见,确实把Level0空着的方法给补上了,而至于从Level1到Level2,那就是正常的一个继承的示例,让大家对于继承更熟些。

当然,这里可能会有小伙伴发现,这次的super前后括号的内容多了好多,原因其实很简单,前面的是Level2的构造函数的形参,后者则是上一个构造函数的形参

5.接口

在很多面向对象语言中,接口是一个重要的概念,它定义了一组方法契约,类可以去“实现 (implement)”这个接口。

接口与继承有什么区别呢?接口的方法必须全部自己实现,而继承则不是:

class Person {String ? name;Person(this.name);String say(){return "我是一个${name}";}
}
//开始接口
class Fperson implements Person {@overrideString ? name;Fperson(this.name);@overrideString say(){return "我是一个${name}(f)";}//接口也可以有自己的方法String inner()=> "我($name(f))是假的嘿嘿";String shiwu()=> "$name(f)暴露了";
}void main(){Person p1 = Person("张三");print(p1.say());Fperson p2 = Fperson("张三");print(p2.say());print(p2.inner());print(p2.shiwu());
}

值得注意的是,在写属性的时候,或者是在写父类的方法时,前面务必加上@override,而如果是自己的方法,则不用加。

关于继承和接口,还有更多的区别,比如接口可以直接多个接口,但是继承一次只能继承一个

接下来,我们进入类的最后一个部分:mixin

6.Mixin--在多个类层次结构中重用代码

Mixin 是一种在多个类层次结构中重用类代码的方式。如果你发现多个类有相似的功能,但它们又不适合放在同一个继承链中,Mixin 就派上用场了。

mixin Qiaodaima{void qiaodaima(){print("正在敲代码");}
}mixin Fei{void fei(){print("正在飞");}
}mixin Jiao{void jiao(){print("正在叫");}
}class Person{String ? name;Person(this.name);
}//这里是继承mixin的例子
class Superperson extends Person with Fei{Superperson(String name):super(name);
}class Person2 extends Person with Qiaodaima{Person2(String name):super(name);
}class Person3 extends Person with Jiao{ Person3(String name):super(name);
//在里面也可以写自己的方法void jiao(){print("我就是想叫");}
}class Person4 with Fei{ // 也可以直接继承mixinString ? name;Person4(this.name);void say(){print("我是${name}, 正在飞");fei();  // 调用mixin中的方法}
}void main(){Superperson s1 = Superperson("超级小明");s1.fei();  // 调用mixin中的方法Person2 p2 = Person2("小明");p2.qiaodaima();  // 调用mixin中的方法Person3 p3 = Person3("小明");p3.jiao();  // 调用mixin中的方法Person4 p4 = Person4("小明");p4.say();
}

在前面协商mixin,表示混入的内容,这里我们定义了三个。

然后在后面的类里面,我们先定义了一个class,作为最基础的类,然后后面通过继承+混入,对不同类型的类加入了不同的mixin,最后使得每个都有其不一样的功能

当然,你也可以在里面加入自己的方法,比如Person3那边

除了继承+混入,其实也可以直接混入,如Person4,由于加入了mixin,所以mixin的方法是可以直接调用的,具体可以见Person4的say方法。

OK,总结一下,今天我们讲了get与set方法,这两个方法可以让我们在别的文件里读取私有属性,然后讲了静态方法和静态属性,这些是继承无法继承的内容,也是独属于当前类的属性,并且可以直接使用类进行调用而不需要先创建实例对象。然后我们讲了继承,通过继承,我们在创建两个类似的类时,就可以考虑先写一个基本的类,再利用继承减少代码量啦!然后讲了抽象类与抽象方法,对于比较抽象的,仅仅是模板的,这个就派上用场啦!最后讲了接口和混入,让类,方法的调用,关系变得更加的多样化,通过接口,接上多个类,通过混入,实现相似的功能提取出来,然后根据不同的类的不同点,分别混入。

那么今天就先到这里啦,今天内容有点多,可能会有些不足的地方,如有问题欢迎指正!祝大家天天开心!代码一遍就通!没有debug的烦恼!

相关文章:

  • Gartner报告解读《Technical Professionals Need to Track 5 ImportantLLM Developments》
  • 论文审稿之我对SCI写作的思考
  • CSS之元素定位
  • 批量获取电商商品数据的解决方案|API接口自动化商品采集|item_get 接口详解
  • 动态规划算法:字符串类问题(2)公共串
  • 【电子通识】FPC连接器组成部分与不良案例术语
  • Day02
  • 嵌入式学习笔记——day25
  • 英伟达破局1000 Token/秒!Llama 4以光速重塑AI推理边界
  • 【深度学习】1. 感知器,MLP, 梯度下降,激活函数,反向传播,链式法则
  • 微信小程序 --三剑客
  • STM32的内部FLASH
  • 「OC」源码学习——KVO底层原理探究
  • 30字速成Docker安装与配置指南
  • urdf文件和DH模型参数是一一对应的吗??
  • PySide6 GUI 学习笔记——常用类及控件使用方法(常用类图标QIcon)
  • ​《分布式年夜》
  • PTA刷题笔记(纠细节 有详解)
  • 【OCCT+ImGUI系列】010-BRepMesh-网格化IncrementalMesh
  • 【Android】非System用户下Persist应用不自动拉起
  • 教师资格证中职网站建设与管理/口碑营销的案例有哪些
  • 海南工程网站建设/百度查一下
  • o2o平台是什么意思/迈步者seo
  • 专业网站设计公司价格/重庆今天刚刚发生的重大新闻
  • 福州市网站建设/google广告
  • 为什么电脑打开那个做网站都是那一个/营销方式和手段