Dart中类和对象的使用大体和Java相似,但是也有一些区别:
一、类与对象
使用关键字new创建对象,但是new 可省略
属性会默认生成getter和setter方法
但是如果是final声明的属性那么只有getter方法,即只读,不能赋值等操作
计算属性:属性的值是通过计算而来,本身并不存储值
如果我们写一个矩形的类以及可以求面积,那么普通方法是:
void main()
{
var a = new Rectangle();
a.height = 5;
a.width = 4;
print(a.area());
}
class Rectangle{
num width,height;
num area(){
return width*height;
}
}
如果用计算属性的话是这样子的
void main()
{
var a = new Rectangle();
a.height = 5;
a.width = 4;
print(a.area);
}
class Rectangle{
num width,height;
num get area{
return width*height;
}
//num get area =>width * height;
}
二、构造方法:
构造方法中不能对final变量赋值。
构造方法不能重载!
void main(){
var moon = new Person("huiying", 28, "female");
print(moon.age);
}
class Person{
String name;
int age;
String gender;
Person(String name,int age,String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
//Person(){}//不能再写这个,会报错,就是因为不能重载
}
那如果我们需要多个构造方法怎么办呢
可以用命名构造方法
用类名.方法来实现
具体实现之后是这样的
void main(){
var moon = new Person("huiying", 28, "female");
print(moon.age);
var key = new Person
}
class Person{
String name;
int age;
String gender;
Person(String name,int age,String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
Person.withName(String name)//可以用命名构造方法来实现重载
{
this.name = name;
}
Person.withage(int age)
{
this.age = age;
}
}
工厂构造方法:
是一种可以返回对象的方法。
在构造方法前面加factory即可。
class Person {
String name;
int age;
String gender;
Person.withAllInfo(this.name,this.age,this.gender);
factory Person()//构造方法前加factory就行
{
return Person.withAllInfo("yue", 28,"female");
}
}
void main(){
var moon = new Person.withAllInfo("huiying", 20, "girl");
print(moon.gender);
}
后期补充:对于构造方法的总结理解
void main() {
Logger log1 = Logger();
Logger log2 = Logger();
print(log1==log2);
}
class Student extends Person{
String _school;
final String city;
String country;
String name;
///构造方法:通过this._school初始化自有参数
///而age,name交给父类进行初始化
///city为可选参数
///country为默认参数
///这两种参数也可以用于其他方法中,
///其实构造方法就是特殊的一种方法而已
Student(this._school, name, int age,{this.city,this.country = 'China'})
: //冒号后边 子类构造器方法体之前的部分我们称为初始化列表
name = '$country--$city--$_school',//可以初始化实例变量,不同的初始化变量之间用逗号分隔!!!逗号!
///父类的构造方法
///如果父类没有无参的构造方法,那么需要在初始化列表中调用父类的构造方法
super(name, age){
print('构造方法体不是必须的');
}
///命名构造方法
///命名方法:类名+.+方法名
///使用命名构造方法为类实现多个构造方法
Student.cover(Student stu,this.city)//如果类的变量有final类型的,将其作为参数
:super(stu.name,stu.age){
print('命名构造方法');
}
///工厂命名构造方法
///可以有返回值(与命名构造方法不同)
///不需要将类的final变量作为参数,比较灵活
factory Student.set(Student stu)
{
return Student(stu._school, stu.name, stu.age);
}
}
///工厂构造方法:
///自我理解感觉就是能够返回对象的方法
///可以用来返回一个之前创造的缓存对象,所以用工厂模式来定义构造方法
class Logger {
static Logger _cache;//创建一个类的实例
factory Logger() //用factory关键字进行标识,通常工厂构造方法是返回唯一的一个实例
{
if(_cache == null)//为了确保返回的实例不为空
{
_cache =Logger._internal(); //如果为空的话那么我们需要调用类的私有的命名构造方法
}
return _cache;
}
Logger._internal();//类的私有的命名构造方法
void log(String msg)
{
print(msg);
}
}
class Person{
String name;
int age;
//标准构造方法
Person(this.name,this.age);
//重写父类方法
@override
String toString() {
return 'name = $name,age = $age';
}
}
三、
初始化列表:
Person.withMap(Map map):gender = map["gender"]
{
this.name = name;
this.age= age;
}
静态成员:
和Java大致类似
静态成员或方法不能访问非静态成员和方法,但非静态的可以访问静态的。
类中的常量需要用static const 来声明
和对象相关的操作符 :
对条件成员的访问 :?. 如果 ? 前面为空的话那么就不往后执行了
void main(){ Person person; person?.printinfo();//如果直接 . 会报错,但如果这样的话就什么都不输出也不报错 } class Person{ String name; int age; String gender; void printinfo() { print("name = $name, age= $age, gender = $gender"); } }
类型转换:as
void main(){ var person; person = ""; person = new Person();//此时person是dynamic的 (person as Person).printinfo();//把person转化为Person的一个对象进行操作才能调用这个函数,直接.不行的 } class Person{ String name; int age; String gender; void printinfo() { print("name = $name, age= $age, gender = $gender"); } }
是否指定类型:is , is!
void main(){ var person; person = ""; person = new Person(); if(person is Person){ person.printinfo(); } } class Person{ String name; int age; String gender; void printinfo() { print("name = $name, age= $age, gender = $gender"); } }
级联操作符: . . 因为返回后还是当前对象,所以可以连着使用调用变量和方法,据说工程上会经常用到
void main(){ var person = new Person(); person..name = "huiying" ..age = 28 ..gender = "female" ..printinfo(); } class Person{ String name; int age; String gender; void printinfo() { print("name = $name, age= $age, gender = $gender"); } }
对象call 方法:
如果类实现了call()方法,则该类的对象可以作为方法来使用
void main(){
var person = new Person();
person("yue",20);
}
class Person{
String name;
int age;
String gender;
// void printinfo()
// {
// print("name = $name, age= $age, gender = $gender");
// }
void call(String name,int age)
{
print("name = $name, age= $age, gender = $gender");
}
}