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

1免费网站建站打开百度竞价页面是网站是什么

1免费网站建站,打开百度竞价页面是网站是什么,网站支付怎么做,电商排行榜10强Kotlin 中的类与接口和 Java 中的类与接口还是有区别的。例如#xff0c;Koltin 中的接口可以包含属性声明#xff0c;与 Java 不同的是。Kotlin 的声明默认是 final 和 public 的。此外#xff0c;嵌套的类默认并不是内部类#xff1a;它们并没有包含对其它外部类的隐式引…Kotlin 中的类与接口和 Java 中的类与接口还是有区别的。例如Koltin 中的接口可以包含属性声明与 Java 不同的是。Kotlin 的声明默认是 final 和 public 的。此外嵌套的类默认并不是内部类它们并没有包含对其它外部类的隐式引用。 1 Kotlin 中的类以及接口 对象是什么任何可以描述的事物都可以看作对象。我们以鸟为例来分析它的组成 形状、颜色等可以看作是鸟的静态属性年龄、大小等可以看作是鸟的动态属性飞行、进食等可以看作是鸟的行为 1.1 Kotlin 中的类 对象是由状态和行为组成的我们可以通过它描述一个事物。 下面就是用 Kotlin 来抽象一个 Bird 类 class Bird {val weight: Double 500.0val color: String blueval age: Int 1fun fly() { // 全局可见} }在 Kotlin 中我们仍然可以使用熟悉的 class 结构体来声明一个类。 但是Kotlin 中的类和 Java 中的类也有很多不同将 Kotlin 代码反编译成 Java 版本 public final class Bird {private final double weight 500.0;NotNullprivate final String color blue;private final int age 1;public final double getWeight() {return this.weight;}NotNullpublic final String getColor() {return this.color;}public final int getAge() {return this.age;}public final void fly() {} }可以看出主要存在以下不同 不可变属性成员Kotlin 支持用 val 在类中声明引用不可变的属性成员这是利用 Java 中的 final 修饰符来实现的使用 var 声明的属性则反之引用可变默认属性值因为 Java 中的属性都是默认值比如 int 类型的默认值为 0引用类型的默认值为 null所以在声明属性的时候我们不需要指定默认值。而在 Kotlin 中除非显式地声明延迟初始化不然就需要指定属性的默认值不同的可访问修饰符Kotlin 类中的成员默认是全局可见的而 Java 的默认可见域是包作用域因此在 Java 的版本中我们必须采用 public 修饰才能达到相同的效果 1.2 可带有属性和默认方法的接口 下面我们继续来看看 Kotlin 和 Java 中接口的差异。 以下是 Java 8 版本的接口 public interface Flyer {public String kind();default public void fly(){System.out.println(I can fly);} }Java 8 引入了一个新特性 —— 接口方法支持默认实现。这使得我们在向接口中新增方法的时候之前继承过该接口的类则可以不需要实现这个新方法。 Kotlin 的接口与 Java 8 中的相似它们可以包含抽象方法的定义以及非抽象方法的实现与 Java 8 中的默认方法类似但它们不能包含任何状态。 接下来看在 Kotlin 中如何声明一个接口 interface Flyer {val speed: Intfun kind()fun fly() {println(I can fly)} }同样我们也可以用 Kotlin 定义一个带有方法实现的接口。同时它还支持抽象属性如上面的 speed。然而Kotlin 是基于 Java 6 的那么它是如何支持这种行为的呢 我们将上面的 Kotlin 声明的接口转换为 Java 代码提取其中关键的代码 public interface Flyer {int getSpeed();void kind();void fly();Metadata(mv {1, 8, 0},k 3)public static final class DefaultImpls {public static void fly(NotNull Flyer $this) {String var1 I can fly;System.out.println(var1);}} }通过以上的代码可以知道Kotlin 编译器是通过定义了一个静态内部类 DefaultImpls 来提供 fly 方法的默认实现的。同时虽然 Kotlin 接口支持属性声明然而它在 Java 源码中是通过 get 方法来实现的。在接口中的属性并不能像 Java 接口那样被直接赋值一个常量。 如以下这样做是错误的 interface Flyer {val height 1000 // error Property initializers are not allowed in interfaces }Kotlin 提供了另外一种方式来实现这种效果 interface Flyer {val heightget() 1000 }这种写法与 Kotlin 实现该机制的背景有关。Kotlin 接口中的属性背后其实是用方法来实现的。所以说如果我们要为变量赋值常量那么就需要编译器原生就支持方法默认实现。但 Kotlin 是基于 Java 6 的当时并不支持这种特性所以我们并不能像 Java 那样给一个接口的属性直接赋值一个常量。 下面我们来看如何在 Kotlin 接口中定义一个普通属性 interface Flyer {val height: Long }它同方法一样若没有指定默认行为则在实现该接口的类中必须对该属性进行初始化。 接下来看如何使用这个接口 class Brid(override val speed: Int) : Flyer {override fun kind() {TODO(Not yet implemented)} }Kotlin 类名后面使用冒号来代替了 Java 中的 extends 和 implements 关键字。和 Java 一样一个类后面可以实现任意接口但是只能继承一个类。 另外和 Java 中的 Override 注解类似override 修饰符用来标注被重写的父类或者接口的方法和属性。与 Java 不同的是在 Kotlin 中使用 override 修饰符是强制要求的。这会避免先写出实现方法再添加抽象方法造成的意外重写我们的代码将不能编译除非我们显式地将这个方法标注为 override 或者重命名它。 总体来说Kotlin 的类与接口的声明和 Java 很类似但它的语法整体上要显得更加简洁。 2 更简洁地构造类的对象 Kotlin 中并没有 new 关键字我们可以通过以下的代码来直接声明一个类的对象 val bird Bird()当前没有给 Bird 传入任何参数。现实中很有可能因为需要传入不同的参数组合而在类中创建多个构造方法在 Java 中这是利用构造方法重载来实现的。 public class Bird {private double weight;private int age;private String color;public Bird(double weight, int age, String color) {this.weight weight;this.age age;this.color color;}public Bird(int age, String color) {this.age age;this.color color;}public Bird(double weight) {this.weight weight;}... }Java 中的这种方式存在两个缺点 如果要支持任意参数组合来创建对象那么需要实现的构造方法将非常多每个构造方法中的代码会存在冗余如前两个构造方法都对 age 和 color 进行了相同的赋值操作 Kotlin 通过引入新的构造语法来解决这些问题。 2.1 构造方法默认参数 要解决构造方法过多的问题似乎也很简单。在 Kotlin 中我们可以给构造方法的参数指定默认值从而避免不必要的方法重载。 现在用 Kotlin 来改写上述的例子 class Bird(val weight: Double 0.00, val age: Int 0, val color: String blue)使用 val bird Bird(color black) val bird2 Bird(weight 1000.00, color black)需要注意的是由于参数默认值的存在我们在创建一个类对象时最好指定参数的名称否则必须按照实际的参数的顺序进行赋值。否则会出现以下错误 我们在 Bird 类中可以用 val 或者 var 来声明构造方法的参数。这一方面代表了参数的引用可变性另一方面它也使得我们在构造类的语法上得到了简化。 为什么这么说呢事实上构造方法的参数名前当然可以没有 val 或者 var然而带上它们之后就等价于在 Bird 类内部声明了一个同名的属性我们可以用 this 来进行调用。 以下是 Bird 类反编译成 Java 代码 public final class Bird {private final double weight;private final int age;NotNullprivate final String color;public final double getWeight() {return this.weight;}public final int getAge() {return this.age;}NotNullpublic final String getColor() {return this.color;}public Bird(double weight, int age, NotNull String color) {Intrinsics.checkNotNullParameter(color, color);super();this.weight weight;this.age age;this.color color;}// $FF: synthetic methodpublic Bird(double var1, int var3, String var4, int var5, DefaultConstructorMarker var6) {if ((var5 1) ! 0) {var1 0.0;}if ((var5 2) ! 0) {var3 0;}if ((var5 4) ! 0) {var4 blue;}this(var1, var3, var4);}public Bird() {this(0.0, 0, (String)null, 7, (DefaultConstructorMarker)null);} }2.2 init 语句块 Kotlin 引入了一种叫做 init 语法块的语法它属于上述构造方法的一部分两者在表现形式上确是分离的。 Bird 类的构造方法在类的外部它只能对参数进行复制。如果我们需要在初始化时进行其他的额外操作那么我就可以使用 init 语句块来执行。比如 class Bird(weight: Double, age: Int, color: String) {init {println(do some other things)println(the weight is ${weight})} }反编译成 Java 代码 public final class Bird {public Bird(double weight, int age, NotNull String color) {Intrinsics.checkNotNullParameter(color, color);super();String var5 do some other things;System.out.println(var5);var5 the weight is weight;System.out.println(var5);} }当没有使用 val 或者 var 的时候构造方法的参数可以在 init 语句块中被直接调用。其实它们还可以用于初始化内部的属性成员的情况。 如 class Bird(weight: Double 0.00, age: Int 0, color: String blue) {val weight: Double weight // 在初始化属性成员时调用 weightval age: Int ageval color: String color }反编译成 Java 代码 public final class Bird {private final double weight;private final int age;NotNullprivate final String color;public final double getWeight() {return this.weight;}public final int getAge() {return this.age;}NotNullpublic final String getColor() {return this.color;}public Bird(double weight, int age, NotNull String color) {Intrinsics.checkNotNullParameter(color, color);super();this.weight weight;this.age age;this.color color;}// $FF: synthetic methodpublic Bird(double var1, int var3, String var4, int var5, DefaultConstructorMarker var6) {if ((var5 1) ! 0) {var1 0.0;}if ((var5 2) ! 0) {var3 0;}if ((var5 4) ! 0) {var4 blue;}this(var1, var3, var4);}public Bird() {this(0.0, 0, (String)null, 7, (DefaultConstructorMarker)null);} }除此之外我们并不能在其他地方使用。以下是一个错误的用法 事实上我们的构造方法还可以拥有多个 init它们会在对象被创建时按照类中从上到下的顺序先后执行。看看以下代码的执行结果 class Bird(weight: Double, age: Int, color: String) {val weight: Doubleval age: Intval color: Stringinit {this.weight weightprintln(The birds weight is ${this.weight})this.age ageprintln(The birds age is ${this.age})}init {this.color colorprintln(The birds color is ${this.color})} }fun main() {val bird Bird(1000.0, 2, blue) }// The birds weight is 1000.0 // The birds age is 2 // The birds color is blue可以发现多个 init 语句块有利于我们进一步对初始化的操作进行职能分离这在复杂的业务开发如 Android中显得特别有用。 再来思考一种场景现实中我们在创建一个类对象时很可能不需要对所有的属性都进行传值。其中存在一些特殊的属性比如鸟的性别我们可以根据它的颜色来进行区分所以它并不需要出现在构造方法的参数列表中。 有了 init 语句块的语法支持我们很容易实现这一点。假设黄色的鸟儿都是雌性剩余的都是雄鸟我们就可以如此设计 class Bird(val weight: Double, val age: Int, val color: String) {val sex: Stringinit {this.sex if (this.color yellow) male else female} }接下来继续修改需求。这一次我们并不想在 init 语句块中对 sex 直接赋值而是调用一个专门的 printSex 方法来进行如 报错了主要由以下两个原因导致 正常情况下Kotlin 规定类中的所有非抽象属性成员都必须在对象创建时被初始化值由于 sex 必须被初始化值上述的 printSex 方法中sex 会被视为二次赋值这对 val 声明的变量来说也是不允许的 第 2 个问题比较容易解决我们把 sex 变成用 var 声明它就可以被重复修改。关于第 1 个问题最直观的方法就是指定 sex 的默认值但这可能是一种错误的性别含义另一种方法是引用可空类型即把 sex 声明为 String? 类型则它的默认值为 null。这可以让程序正确运行然而实际上也许我们又不想让 sex 具有可空性而只是想稍后再进行赋值所以这种方案也有局限性。 2.3 延迟初始化by lazy 和 lateinit 更好的做法是让 sex 能够延迟初始化即它可以不用在类对象初始化的时候就必须有值。 在 Kotlin 中我们主要是使用 lateinit 和 by lazy 这两种语法来实现延迟初始化的效果。 下面来看如何使用它们如果这是一个用 val 声明的变量我们可以用 by lazy 来修饰 class Bird(val weight: Double, val age: Int, val color: String) {val sex: String by lazy {if (color yellow) male else female} }by lazy 的语法特点如下所示 该变量必须是引用不可变的而不能用 var 来声明在被首次调用时才会进行赋值操作。一旦被赋值后续它将不能被更改 lazy 背后是接受一个 lambda 并返回一个 LazyT 实例的函数第一次访问该属性的时候会执行 lazy 对应的 Lambda 表达式并记录结果后续访问该属性时只是返回记录的结果。 另外系统会给 lazy 属性默认加上同步锁也就是 LazyThreadSafetyMode.SYNCHRONIZED它在同一时刻只允许一个线程对 lazy 属性进行初始化所以它是线程安全的。但是如果能确认该属性可以并行执行没有线程安全问题那么可以给 lazy 传递 LazyThreadSafetyMode.PUBLICATION 参数。我们还可以给 lazy 传递 LazyThreadSafetyMode.NONE 参数这将不会有任何线程方面的开销当然也不会有任何线程安全的保证。 比如 val sex: String by lazy(LazyThreadSafetyMode.PUBLICATION) {// 并行模式if (color yellow) male else female }val sex: String by lazy(LazyThreadSafetyMode.NONE) {// 不做任何线程保证也不会有任何线程开销if (color yellow) male else female }与 lazy 不同lateinit 主要用于 var 声明的变量然而它不能用于基本数据类型如 Int、Long 等我们需要用 Integer 这种包装类作为替代 class Bird(val weight: Double, val age: Int, val color: String) {lateinit var sex: String // sex 可以延迟初始化fun printSex() {this.sex if (this.color yellow) male else femaleprintln(this.sex)} }fun main() {val bird Bird(1000.0, 2, blue)bird.printSex() }// female那么是如何让用 var 声明的基本数据类型变量也具有延迟初始化的效果一种可参考的解决方案是通过 Delegates.notNullT这是利用 Kotlin 中委托的语法来实现的。 var test by Delegates.notNullInt()fun doSomething() {test 1println(test value is $test)test 2 }总而言之Kotlin 并不主张用 Java 中的构造方法来重载来解决多个构造参数组合调用问题。取而代之的方案是利用构造参数默认值及用 val、var 来声明构造参数的语法以便更简洁地构造一个类对象。 3 主从构造方法 有些时候我们可能需要从一个特殊的数据中获取构造类的参数值这时候如果可以定义一个额外的构造方法接收一个自定义的参数会显得特别方便。 同样以鸟为例先把之前的 Bird 类简化为 class Bird(age: Int) {val age: Intinit {this.age age} }假设当前我们知道鸟的生日希望可以通过生日来得到鸟的年龄然后创建一个 Bird 类对象。如何实现 第 1 种方案是在别处定义一个工厂方法如 fun Bird(birth: Date) Bird(getAgeByBirth(birth))应该在哪里声明这个工厂方法呢这种方式的缺点在于Bird 方法与 Bird 类的代码层面的分离显得不够直观。 另外我们还可以像 Java 那样新增一个构造方法来解决这个问题。其实Kotlin 也支持多构造方法的语法然而与 Java 的区别在于它在多构造方法之间建立了“主从”的关系。 我们下面来用 Kotlin 中的多构造方法实现这个例子 class Bird(age: Int) {val age: Intinit {this.age age}constructor(birth: Date) : this(getAgeByBirth(birth)) {... } }下面来看看这个新的构造方法是如何运作的 通过 constructor 方法定义了一个新的构造方法它被称为从构造方法。相应地我们熟悉的在类外部定义的构造方法被称为主构造方法 每个类可最多存在一个主构造方法和多个从构造方法如果主构造方法存在注解或可见性修饰符也必须像从构造方法一样加上 constructor 关键字internal public Bird inject constructor(age: Int) { } 每个从构造方法由两部分组成。一部分是对其他构造方法委托另一部分是由花括号包裹的代码块。执行顺序上会先执行委托的方法然后执行自身代码块的逻辑。 通过 this 关键字来调用要委托的构造方法。如果一个类存在主构造方法那么每个从构造方法都要直接或者间接的委托给它。比如可以把从构造方法 A 委托给从构造方法 B再将从构造方法 B 委托给主构造方法。 举个例子 class Bird(age: Int) {val age: Intinit {this.age age}constructor(timestamp: Long) : this(DateTime(timestamp)) // 构造函数 Aconstructor(birth: DateTime) : this(getAgeByByBirth(birth)) // 构造函数 Bfun getAgeByByBirth(birth: DateTime): Int {return Year.yearsBetween(birth, DateTime.now()).years}}其实从构造方法的设计除了解决我们以上的场景之外还有一个很大的作用就是可以对某些 Java 类库进行很好的扩展因为我们经常要基于第三方 Java 库中的类扩展自定义的构造方法。典型的例子就是定制业务中特殊的 View 类。 比如以下代码 class KotlinView : View {constructor(context: Context) : this(context, null)constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context,attrs,defStyleAttr)}可以看出利用从构造方法我们能使用不同参数来初始化第三方类库中的类了。
http://www.zqtcl.cn/news/64292/

相关文章:

  • 现在建网站赚钱吗山西长治做网站公司有哪些
  • vue cdn做的网站免费咨询医生回答在线
  • 宏杰zkeys网站模板wordpress title优化
  • 做视频网站是什么职业科协网站页建设的意义
  • 网站开发过程总结门户网站建设思维导图
  • 房山建站公司网站定制开发是什么
  • 有什么网站可以做微信app电商网站开发prd
  • 深圳网站优化网站深圳市哪些公司做网站好
  • 做网站用哪种语言好wordpress判断
  • 知舟网站建设c2c的网站有哪些
  • 做暧网站免费网站开发需要服务器吗
  • 目前做那些网站能致富帮忙做任务网站
  • 企业门户网站设计论文大连网站建设哪个公司好
  • 麻涌公司网站建设公司做网站为什么要用php
  • 西宁专业网站建设公司电商怎么做?如何从零开始学做电商赚钱
  • 可以注销的网站企业网站建设方案论文
  • 公司网站如何建设教程设计素材网站版权问题
  • 网站建设文字表达百度推广费用多少钱
  • 用网站做数据库吗手机软件app下载
  • 文安做网站福田住房和建设局网站官网
  • ipsw 是谁做的网站网页制作搜题软件
  • 北京中国建设银行招聘信息网站用路由器做网站
  • 南京网站设计公司兴田德润优惠吗国外虚拟服务器网站
  • 桓台网站建设玉林网站seo
  • 静态网站什么意思重庆建设集团
  • 天津品牌网站建设好处安卓系统软件开发培训
  • 国外自适应网站模版长沙房产信息网官网
  • 马鞍山建设工程监督站建管处网站婚礼做的好的婚庆公司网站
  • 中山商城网站建设会计培训网站
  • 手机建站网社交网站建设网