复习:面向对象:类成员:构造函数 / 属性 / 析构(垃圾回收)
即一个类中可以有多个参数不同的构造函数,如下所示:
class Student { public Student(String name){} public Student(String name, int age){} }
调用的时候,按方法重载规则进行匹配。
同时你会发现再也不能使用new Student()调用无参的构造函数了。这是因为:一旦声明了任何构造函数,之前默认自带的隐式的(implicit)无参构造函数消失。
如果你还想保留无参构造函数,需要在类中显式(explicit)的声明。
class Student { public Student() {}
在一个类的内部声明的类被称之为内部类。
内部类和外部类之间可以互相访问(即使是private的)。
class Student { private void learn() { new Score().add(); } class Score{ private void add() { new Student().learn(); } } }但是,
// new Student().Score 没有这种写法
class Student { /* private */ static class Score{
Student.Score ss = new Student.Score(); //此时Score不能被private修饰
复习:面向对象:继承 / protected / 父类装子类 / 类型转换 / 滥用
继承为类的实例化带来了一个问题:
实例化一个子类,需要首先调用它(全部的,即包含祖先的)父类构造函数。因为父类成员的存在,必须是在类的实例化之后(任何类都一样,你要使用这个类的实例成员,当然要先对这个类实例化一次——实例化就必须通过调用构造函数实现)。
子类默认会调用父类的无参构造函数。
断点演示:显式声明/隐藏无参构造
class Person { public Person() { //断点自动击中;如果被隐藏,会报编译错误 } public Person(int age) { } }
但是,如果父类没有无参构造函数,就需要在子类的构造函数中指定具体调用父类的哪一个构造函数:
class Student extends Person { public Student() { super(18); //对应this() } }
演示:再添加一个基类:
class Entity{
class Student extends Person {
new Student()时要从Entity的构造函数开始。
Java中的关键字是final(和常量关键字相同,意思是不变了),C#中关键字是sealed(封闭的)
演示:
final class Person {
public final void Eat() {
由abstract定义的方法叫做抽象方法,抽象方法不能有方法体({}都不能有,空的也不行),只能放置在被abstract修饰的抽象类中。
//要在类中声明abstract方法,类上就必须加abstract abstract class Person { //abstract修饰的方法不能有方法体! public abstract void Eat(); }
抽象类有一个非常明显的特点:不能被实例化!
new Person(); //报错能实例化的是它的子类:
new Student(); //OK class Student extends Person {
注意抽象方法的子类必须实现抽象方法里面的全部抽象方法:(所以抽象方法也不能private)
因为抽象方法没有方法体,所以子类也不能通过base调用其父类的抽象方法。
由interface关键字声明的……和类极其类似的那玩意儿……叫做接口:
interface IMove { //C#中接口惯例加“I”作为前缀(Java没有)
接口和抽象类非常类似。
抽象方法也可以放在接口中:
interface IMove { void Walk(); int Run(int miles); }
接口一样不能实例化。
接口一样可以被“继承”,但我们将其称之为“实现(implement)”,子类实现接口用的关键字是implements(但C#中仍然使用冒号(:))
class Teacher implements IMove {
接口的子类,都必须实现接口中定义的全部抽象方法。(演示:F2 auto fix自动生成)
一个类可以同时继承基类并实现(多个)接口,比如:
,同时继承和实现
常见面试题:接口和抽象类有什么区别?
注意首先声明:所谓接口,是传统意义上的接口。
最简单的回答是从语法层面来说,比如:(演示:)
|
抽象类 |
接口 |
非抽象方法 | 可以有(@想一想@:为什么,有啥用?) | 不能有 |
构造函数 | 可以有 | 不能有 |
子类可继承/实现 | 一个 | 多个 |
普通字段(@想一想@:属性呢?) | 可以有 | 不能有(新版本才可以有条件的有……) |
相互间 | 可以实现接口 | 不能继承抽象类 |
访问修饰符 | 可以protected | 默认/只能public |
但实际上,因为面向对象是代码管理的工具,我们更应该透过语法探究其所需要表达的意义:
抽象类还是一个类,类通常都被认为是对现实中事物的映射,是对事物的行为和状态的抽象。所以,类名一般都是名词(比如Person、Animal、Major之类的),既有行为(方法)也有状态(字段),其中:
你真要完成挣钱这事,还得依赖具体的实例:
Career career = new Career(); //怪异,这职业究竟是啥职业? Career career = new Layer(); //OK了,律师这种职业对象,不错而接口,从语法角度,interface也是一种class
IMove atai = new Student(); //父类变量装子类对象但它通常被认为是对行为(没有状态)的抽象,所以接口名一般都是动词(比如IMove、ILearn),映射的是一些操作,其中只有方法(属性本质上也是一种方法)。
最后,相较于普遍基类,抽象类和接口是一种更纯粹的抽象。纯粹度:接口 > 抽象类 > 普通父类
即应用接口(application interface)。
是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
说人话:应用程序对外部提供的一系列抽象方法/方法定义(即:不带方法体部分),外部可以:
理解接口,最好的例子:usb接口。
但注意:接口本身不实现任何东西。
复习:面向对象:多态:override / 为什么 / 抽象类 / 接口
Java 8 / C# 8.0,从时间上看,是C#模仿的Java。
居然可以在接口中出现方法体/实现了:
default void Walk() { System.out.println("迈着六亲不认的步伐"); }但是,注意:
实现类对象可以直接调用接口中的默认方法:
new Person().Walk();
接口中还可以有静态方法:
static double getSpeed() { return 98.6; }
一样不能private/protected啥的。
以及静态常量字段:public static final double speed = 70;
public、static和final都可以省略,因为是默认且不可更改的。
接口中的静态方法通常用于default方法中:
default void Walk() { System.out.println("迈着六亲不认的步伐,速度" + getSpeed()); }
---------- 在学习完 Java和C#类库后完成 ----------
多快好省!前端后端,线上线下,名师精讲
更多了解 加: