《javascript设计模式》笔记之第四章:继承
function Person(name) {
this.name = name;
} Person.prototype.getName = function() {
return this.name;
}
下面是创建一个子类Author,用于继承Person:
分两步,第一步继承父类的属性,第二部继承父类的公共方法
function Author(name, books) {
Person.call(this, name); // 通过这一行代码可以继承父类的属性
this.books = books; // 子类增添自己的属性
} Author.prototype = new Person(); // 继承父类方法的第一行代码
Author.prototype.constructor = Author; // 继承父类方法的第二行代码
Author.prototype.getBooks = function() { // 子类增添自己的方法
return this.books;
};
这样就完成了一个简单的继承
二:编写一个extend函数来简化类的声明:
extend函数:
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
}
extend的函数作用有两个,一为简化代码,二就是使继承父类方法的时候不用运行父类的构造函数然后Author这个子类的定义就变成了这样:
function Author(name, books) {
Person.call(this, name);
this.books = books;
}
extend(Author, Person); Author.prototype.getBooks = function() {
return this.books;
};
到目前为止,我们要调用超类的方法,是要以Person开头来调用的(例如:Person.call。。。。等),如果我们想要通过Author开头来调用父类的方法,我们就要对extend函数做一些改动改进的extend函数:
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass; subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
利用上面的倒数第五行代码,我们就可以使子类可以调用通过Author.这种方法调用父类的方法了(这样做是为了不让Person出现在Author类的定义中),然后我们就可以把Author的定义改成以下:
function Author(name, books) {
Author.superclass.constructor.call(this, name);
this.books = books;
}
extend(Author, Person); Author.prototype.getBooks = function() {
return this.books;
}; Author.prototype.getName = function() {
var name = Author.superclass.getName.call(this);
return name + ', Author of ' + this.getBooks().join(', ');
};
这样的话,Author的定义中,除了extend函数中有出现过Person,其他地方都没有出现Person了~三: 原型式继承:接下来,我们使用原型式继承来重新设计Person和Author:首先,clone函数(按照书上的顺序,这个可以先不看):
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
步骤一(定义Person原型):
var Person = {
name: 'default name',
getName: function() {
return this.name;
}
};
步骤二(通过原型式继承,创建Author原型):
var Author = clone(Person);
Author.books = []; // Default value.
Author.getBooks = function() {
return this.books;
}
步骤三(使用):
var author = []; author[] = clone(Author);
author[].name = 'Dustin Diaz';
author[].books = ['JavaScript Design Patterns']; author[] = clone(Author);
author[].name = 'Ross Harmes';
author[].books = ['JavaScript Design Patterns']; author[].getName();
author[].getBooks();
通过这样的方法,传统意义的类就变成这样一个个的对象了!(虽然在javascript中类也是对象。。。)这种方法的特点就是所有对象共用一个对象原型,其实就是这么简单。但是这导致的一个问题就是读和写的不对等。下面例子说明这个问题:
var authorClone = clone(Author);
alert(authorClone.name); // 调用的其实是Person.name
// 所以输出的是字符串'default name'.
authorClone.name = 'new name'; // 这样做其实就是在自己的对象中创建一个name属性
alert(authorClone.name); // 这样再使用name属性的时候,就会变成使用自己的name属性,而不是原型上的Person.name了
// 所以这时候的值是'new name'
authorClone.books.push('new book'); // 对于数组也就是一样的道理,这行代码没有创建自身的books属性,等于直接操作原型里面的属性,所以就会导致原型的默认值编程‘new book’了,这会作用到其他使用原型继承的其他对象当中
authorClone.books = []; // 所以解决的方法就是在自身的对象中新建一个books数组
authorClone.books.push('new book'); // 然后再进行对数组的操作
提示,通过hasOwnProperty可以去分对象的实际成员和它继承而来的成员
此外,上述的这种情况对于拥有对象属性的原型来说也是一样,其实我们也可以用同一种办法来解决,例如下面这个实例:
var CompoundObject = {
string1: 'default value',
childObject: {
bool: true,
num:
}
} var compoundObjectClone = clone(CompoundObject); // 这样做的话就会破坏原型的默认值了
compoundObjectClone.childObject.num = ; // 这个解决方法和上面数组那个一样,在自身的原型里面创建一个心的childObject对象
compoundObjectClone.childObject = {
bool: true,
num:
};
但是,问题又来了,我想要知道默认值的情况下创建自身的childObject对象要怎样做呢?下面就是一种解决方法,利用工厂方法来创建自身的childObject
var CompoundObject = {};
CompoundObject.string1 = 'default value',
CompoundObject.createChildObject = function() {//这个函数是关键,返回一份副本
return {
bool: true,
num:
}
};
CompoundObject.childObject = CompoundObject.createChildObject();//这里就在原型里面先获取一次这个对象副本,原型就有了childObject属性 var compoundObjectClone = clone(CompoundObject);
compoundObjectClone.childObject = CompoundObject.createChildObject();//这里就创建新对象自己的childObject属性
compoundObjectClone.childObject.num = 5;
四: 类式继承和原型式继承的对比:类式继承的优点就是很多人都知道原型式继承的优点就是代码简洁,并且节约内存(因为如果克隆出来的对象不新建自己的属性的话,那么就只有原型上的一份公共副本而已)五: 继承与封装:
如果要继承的话,最好父类使用门户大开方法
六: 掺元类:javascript中只能继承一个父类,所以如有一些不需要严格继承,但是很多类都用到的方法,我们就通过扩充的方式让这些类共享这些方法,例子:一个类(其实就是包含一个简单的toJSONString方法):
var Mixin = function() {};
Mixin.prototype = {
serialize: function() {
var output = [];
for(key in this) {
output.push(key + ': ' + this[key]);
}
return output.join(', ');
}
};
我们很多类都需要用到上面这个类的serialize方法,所以我们就用扩充函数来扩充需要这个方法的类(扩充函数的具体代码下面会给出):
augment(Author, Mixin);
让后就可以使用了:
var author = new Author('Ross Harmes', ['JavaScript Design Patterns']);
var serializedString = author.serialize();
现在给出augment函数的具体代码:
function augment(receivingClass, givingClass) {
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
其实就是遍历有没有同名的方法,没有的话就添加到要扩展的类中。如果想要只扩展某些方法,而不是全部方法,那么就改进一下augment函数:
function augment(receivingClass, givingClass) {
if(arguments[]) { // Only give certain methods.
for(var i = , len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
}
else { // Give all methods.
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
改进的augment函数可以选传第三个以后的参数,这些参数都是方法名。然后函数会检测有没有选传的参数,如果有的话就只扩展与这些参数同名的方法。否则扩展全部方法。七: 示例:就地编辑:
下面就是使用一个例子,来演示上所说的三种方法。
例子说明:假设你的任务就是编写一个用于创建和管理就地编辑域的可重用的模块化API(就地编辑是指网页上的一段普通文本被点击后就变成一个配有一些按钮的表单域,以便用户对这段文本进行编辑)。使用这个API,用户应该能够为对象分配一个唯一的ID值,能够为它提供一个默认值,并且能够指定其在页面上的目标位置。用户还应该在任何时候都可以访问到这个域的当前值,并且可以选择具体使用的编辑域(比如多行文本框或单行文本框)。
也就是说,平时是这个样子的:
点击之后会变成这样在的:
文本框中填写"改变文本",save后:
接下来,我们的需求更改了,要把input框变成textarea框,怎么办了?也就是说
点击之后要变成这样子:
方法一:类式继承解决方案
首先创建一个父类EditInPlaceField以及演示它的使用:
<html> <head>
<meta http-equiv="charset" content="utf-8"></head> <body>
<script>
//类的定义
function EditInPlaceField(id, parent, value) {
this.id = id;
this.parentElement = parent;
this.value = value || 'default value'; this.createElements(this.id);
this.attachEvents();
} EditInPlaceField.prototype = {
createElements: function (id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('span');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('input');
this.fieldElement.type = 'text';
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
},
attachEvents: function () {
var that = this;
this.staticElement.addEventListener('click', function () {
that.convertToEditable();
},false);
this.saveButton.addEventListener('click', function () {
that.save();
},false);
this.cancelButton.addEventListener('click', function () {
that.cancel();
},false);
},
convertToEditable: function () {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
},
save: function () {
this.value = this.getValue();
this.convertToText();
},
cancel: function () {
this.convertToText();
},
convertToText: function () {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'inline'; this.setValue(this.value);
}, setValue: function (value) {
this.fieldElement.value = value;
this.staticElement.innerHTML = value;
},
getValue: function () {
return this.fieldElement.value;
}
} //类的使用
var body = document.body;
var titleClassical = new EditInPlaceField('titleClassical', body, 'Title Here');
</script></body> </html>
接下来,就演示如何通过继承来把input装换成textarea框,增添的代码如下:
function extend(subClass, superClass) {
var F = function () {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass; subClass.superclass = superClass.prototype;
if (superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
} //继承
function EditInPlaceArea(id, parent, value) {
EditInPlaceArea.superclass.constructor.call(this, id, parent, value);
};
extend(EditInPlaceArea, EditInPlaceField); EditInPlaceArea.prototype.createElements = function (id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('p');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('textarea');
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
};
EditInPlaceArea.prototype.convertToEditable = function () {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'block';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
};
EditInPlaceArea.prototype.convertToText = function () {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'block'; this.setValue(this.value);
}; var AreaObject = new EditInPlaceArea('AreaObject', body, '多行文本框默认值');
继承之后,再重写相应的方法,就完成了所有需求了。
方法二:原型式继承解决方案
第一步:
<html> <head>
<meta http-equiv="charset" content="utf-8"></head> <body>
<script>
function clone(object) {
function F() {}
F.prototype = object;
return new F;
} var EditInPlaceField = {
configure: function (id, parent, value) {
this.id = id;
this.value = value || 'default value';
this.parentElement = parent; this.createElements(this.id);
this.attachEvents();
},
createElements: function (id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('span');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('input');
this.fieldElement.type = 'text';
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
},
attachEvents: function () {
var that = this;
this.staticElement.addEventListener('click', function () {
that.convertToEditable();
}, false);
this.saveButton.addEventListener('click', function () {
that.save();
}, false);
this.cancelButton.addEventListener('click', function () {
that.cancel();
}, false);
}, convertToEditable: function () {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
}, save: function () {
this.value = this.getValue();
this.convertToText();
}, cancel: function () {
this.convertToText();
},
convertToText: function () {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'inline'; this.setValue(this.value);
}, setValue: function (value) {
this.fieldElement.value = value;
this.staticElement.innerHTML = value;
},
getValue: function () {
return this.fieldElement.value;
}
}; var body = document.body;
var titlePrototypal = clone(EditInPlaceField);
titlePrototypal.configure('titlePrototypal ', body, 'Title Here');
</script></body> </html>
第二步继承,添加的代码:
var EditInPlaceArea = clone(EditInPlaceField); EditInPlaceArea.createElements = function (id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('p');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('textarea');
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
};
EditInPlaceArea.convertToEditable = function () {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'block';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
};
EditInPlaceArea.convertToText = function () {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'block'; this.setValue(this.value);
}; //使用
var editInPlaceArea = clone(EditInPlaceArea);
editInPlaceArea.configure('editInPlaceArea ', body, 'editInPlaceArea');
这样就完成了,其实,相对于第一种方法,改动是很少的~。
方法三:掺元类解决方案
先把扩展类复制进代码中:
function augment(receivingClass, givingClass) {
if (arguments[]) { // Only give certain methods.
for (var i = , len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
} else { // Give all methods.
for (methodName in givingClass.prototype) {
if (!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
然后创建一个包含了所有要共享的方法的类:
var EditInPlaceMixin = function() {};
EditInPlaceMixin.prototype = {
createElements: function(id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('span');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('input');
this.fieldElement.type = 'text';
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
}, attachEvents: function() {
var that = this;
this.staticElement.addEventListener('click', function() {
that.convertToEditable();
}, false);
this.saveButton.addEventListener('click', function() {
that.save();
}, false);
this.cancelButton.addEventListener('click', function() {
that.cancel();
}, false);
}, convertToEditable: function() {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
}, save: function() {
this.value = this.getValue();
this.convertToText();
}, cancel: function() {
this.convertToText();
},
convertToText: function() {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'inline'; this.setValue(this.value);
}, setValue: function(value) {
this.fieldElement.value = value;
this.staticElement.innerHTML = value;
},
getValue: function() {
return this.fieldElement.value;
}
};
下一步就是创建一个EditInPlaceField类,然后扩展它
function EditInPlaceField(id, parent, value) {
this.id = id;
this.value = value || 'default value';
this.parentElement = parent; this.createElements(this.id);
this.attachEvents();
};
augment(EditInPlaceField, EditInPlaceMixin);
像第一种方法一样使用
var body = document.body;
var titleClassical = new EditInPlaceField('titleClassical', body, 'Title Here');
将input框变成textarea的做法如下:首先创建EditInPlaceArea构造方法:
function EditInPlaceArea(id, parent, value) {
this.id = id;
this.value = value || 'default value';
this.parentElement = parent; this.createElements(this.id);
this.attachEvents();
};
添加要重写的方法:
EditInPlaceArea.prototype.createElements = function (id) {
this.containerElement = document.createElement('div');
this.parentElement.appendChild(this.containerElement); this.staticElement = document.createElement('p');
this.containerElement.appendChild(this.staticElement);
this.staticElement.innerHTML = this.value; this.fieldElement = document.createElement('textarea');
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement); this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = 'Save';
this.containerElement.appendChild(this.saveButton); this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = 'Cancel';
this.containerElement.appendChild(this.cancelButton); this.convertToText();
};
EditInPlaceArea.prototype.convertToEditable = function () {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'block';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline'; this.setValue(this.value);
};
EditInPlaceArea.prototype.convertToText = function () {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'block'; this.setValue(this.value);
};
最后才是扩展:
augment(EditInPlaceArea, EditInPlaceMixin);
使用:
var AreaObject = new EditInPlaceArea('AreaObject', body, '多行文本框默认值');
其实这种方法用在这个例子上是不是很适合的,因为上面那两个类都很相似,导致要先重写一些方法再扩展。
《javascript设计模式》笔记之第四章:继承的更多相关文章
- Javascript设计模式笔记
Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...
- 【NPDP笔记】第四章 文化组织与团队
此为临时链接,仅用于预览,将在短期内失效.关闭 [NPDP笔记]第四章 文化组织与团队 小康 小康哥的产品之路 9月6日 4.1 文化和氛围对创新的重要性 文化:信念,价值观,假设,与期望 氛围:直接 ...
- [书籍翻译] 《JavaScript并发编程》第四章 使用Generators实现惰性计算
本文是我翻译<JavaScript Concurrency>书籍的第四章 使用Generators实现惰性计算,该书主要以Promises.Generator.Web workers等技术 ...
- Java程序猿JavaScript学习笔记(2——复制和继承财产)
计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...
- win32多线程程序设计笔记(第四章下)
上一笔记讲了同步机制中的临界区域(Critical Sections).互斥器(Mutexes),下面介绍同步机制中的另外两种. 信号量(Semaphores) 举个例子: 现在有人要租车,接待他的代 ...
- 05 技术内幕 T-SQL 查询读书笔记(第四章)
第四章 子查询:在外部查询内嵌套的内部查询(按照期望值的数量分为,标量子查询 scalar subqueries,多值子查询multivalued subqueries)(按照子查询对外部查询的依赖性 ...
- javascript - 工作笔记 (事件四)
在javascript - 工作笔记 (事件绑定二)篇中,我将事件的方法做了简单的包装, JavaScript Code 12345 yx.bind(item, "click&quo ...
- Linux内核分析 读书笔记 (第四章)
第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有通过调度程序的合理调度,系统资源才能最大限 ...
- 《深入理解java虚拟机》读书笔记三——第四章
第四章 虚拟机性能监控与故障处理工具 1.JDK命令行工具 jps命令: 作用:列出正在运行的虚拟机进程. 格式:jps [option] [hostid] 选项:-q 只输出LVMID(Local ...
随机推荐
- html5--5-4 绘制矩形
html5--5-4 绘制矩形 学习要点 掌握绘制矩形的方法:strkeRect()/fillRect() 掌握绘制路径的 beginPath()和closePath() 矩形的绘制方法 rect(x ...
- dancing link 精确覆盖 重复覆盖 (DLX)
申明:因为转载的没有给出转载链接,我就把他的链接附上,请尊重原创: http://www.cnblogs.com/-sunshine/p/3358922.html 如果谁知道原创链接 给一下,请尊重原 ...
- Python:元组
元组:只读,不能修改,使用小括号 创建元组: tup1 = ('physics', 'chemistry', 1997, 2000) tup2 = (1, 2, 3, 4, 5 ) tup3 = &q ...
- linux c++ 连接mysql 数据库
Mysql是数据库中的主流,因此我一直以为在Linux下配置会很很容易,结果Google了大半天,大部分网页只说了如何安装Mysql之类的废话,对如何使用C/C++连接Mysql却只字不提,或者提的方 ...
- codevs 3095 黑心的市长
3095 黑心的市长 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description A市有一条长Nkm的高速公路.有M个人各自想承包 ...
- Tinyplay
android里面的目录:external/tinyalsa 编译: 1. cd external/tinyalsa/ 2. vi Android.mk 3. mmm . 4. 拷贝出可执行文件 执行 ...
- PICO 中关于时基ps3000aGetTimebase函数介绍
- 5、html的body内标签之多行文本及下拉框
一.多行文本 <textarea name="">默认值</textarea> 二.下拉框 1.单选 <select name="city& ...
- Flutter实战视频-移动电商-09.首页_项目结构建立和获取数据
09.首页_项目结构建立和获取数据 在config下创建service_url.dart 用来配置我们后端接口的配置文件 一个变量存 接口地址,一个接口方法地址 所有后天请求数据的方法都放在这个文件夹 ...
- LuaToC#
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...