【Java 小白菜入门笔记 2.1】面向对象相关

实验网址:https://www.shiyanlou.com/courses/1230

类(class)

作为面向对象的Java,一切皆对象(类的实例)。用关键字class定义。
类中含有属性(变量)和方法(函数)。
变量的类型:

  1. 局部变量(定义在方法体中,用完就销毁);
  2. 成员变量(顾名思义,即class的成员,定义在方法体外,class内,这种可以被方法访问,在创建class的对象时即实例化);
  3. 静态变量(用static声明,位置与成员变量一样)

创建对象的方法

类名 对象名 = new 类名()

其实这个在前面创建基本数据类型的时候已经描述过了。比如int、string之类。如String类:

String str = new String("test")

需要注意的一个问题:局部变量和成员变量重名时,局部变量具有更高优先级。

构造方法:与类名同名,无返回值。
如果不写构造方法,则自动生成一个无参构造方法,如果写了,则不再生成无参数的构造方法。另外,多个不同的构造方法可以实现重载。

对象名实际上指代的是一个对对象实例的引用。用 == 来比较两个对象名,则实际上是在比较这两个对象名是不是指向同一个对象。(与C中的指针类似)。

static:静态变量和静态方法。这个是属于class共有的,而非其一个实例(对象)所有。因此,用static修饰的变量或方法可以不通过对象,而是直接用class来访问。
由此可以合理推出:static的方法里面不能用this,也不能用非静态的变量和方法。因为这些东西都必须经过了实例化才能用。如果static里面调用了这些非静态的,那么也就没法直接用class调用了。

class的概念有点类似柏拉图的理念。一匹理念世界的马可以形成现实世界中的多匹不同的马,而static则表示了马的一些固有属性,比如 num_legs = 4,或者has_tail = true,或者定义一个方法 run()。这些属性和方法是所有的马共有的,也就是马这个理念所带有的。因此不需要实例化一匹马出来,我们就能知道所有的马都是四条腿的。

final关键字:顾名思义,final 为最终版的意思,用final修饰的class不能被继承,修饰的方法不能被重写,修饰的变量不能被修改(也就成了常量)。

权限修饰符:public、private、protected
其中 public为公开,所有都可以用
private仅限于本class中用。
protected为本class和子类可用。
如果不加修饰符,则本类和同包内可用。

class中进行封装,通常会设置setter和getter方法,用于读取和修改private var。其好处是可以在方法中进行一些控制,比如过滤非法字符,保证安全。

this关键字用来调用属性和方法,和python类似。

继承:子类(派生类)继承父类(基类)。
格式为:

class 子类 extends 父类

继承的作用:代码复用。
继承可以实现的功能:除了private,父类的属性和方法可以访问和使用。另外,还可以重写父类的函数。当然,也可以在加入自己的属性和方法。
Java的继承是单继承。

在子类中调用父类时,用super关键字。
比如 super.属性 super.方法 可以获得父类的属性和方法
而在子类最前面super(),可以调用父类的构造函数

重载:需要保证参数不同;
重写:需要保证参数、返回值类型数量相同。

多态:必要条件:继承、重写、向上转型。
向上转型: 父类名 对象名(引用) = new 子类名()
也就是说,引用是父类的引用,子类必然包含了父类的变量和方法,因此可行(相反则不行)。
向上转型后,子类特有的变量方法被遗忘,父类的部分方法可能被重写。

抽象类:以abstract关键字标识,可以含有抽象方法,即只声明,不实现。不能直接实例化一个抽象类,需要用子类进行继承重写。往往加上@override标记出重写的方法。

接口:用interface标识。基本形态如下:

// MyInterface.java
interface MyInterface{
	int label = 1; // static final类型
	public void MyMethod(); // 必须为抽象类
}

前面说了,Java里class不能多继承,但是interface可以。

// 多重继承的实现,interface 用 extends 继承
修饰符 interface A extends 接口1,接口2{
}
// class 实现接口,需要用 implements
修饰符 class A implements 接口1,接口2{
}

接口 和 接口的方法 都是隐式抽象的,不写abstract也是抽象。
接口的方法都是public的。
接口的变量都是静态常量,也是public的。
换句话说,接口的方法都是自带这个的: public abstract
而接口的变量, 自带这个修饰符:public static final

一个类class要是想实现接口,必须实现其中所有的方法。
如果不实现,那么这个class也必须是一个abstract 抽象类。

内部类:就是类中定义的类,套娃。
内部类编译完成后和外部类是两个class,因此可以方法变量的同名。
内部类可以使用外部类的所有方法和变量。

内部类如何进行实例化?一个栗子:
这里People为外部类,Student为内部类。stuInfo为Student内部类的一个成员函数。

People a = new People();     //创建外部类对象,对象名为a
Student b = a.new Student(); //使用外部类对象创建内部类对象,对象名为b
							 // 或者为 People.Student b = a.new Student();
b.stuInfo();   //调用内部对象的suInfo方法

可以看到,这个new用的是已经实例化的一个外部类的对象的new,其它操作都一样。

内部类里面不能有static,因为static不需要实例化就能用,而内部类必须要用实例化后的外部类的对象进行创建。

对内部类加一个static,就成了 静态内部类。
静态内部类的特点,它只能访问(直接访问,不用new对象的那种)外部类的static变量。
另外,静态内部类可以直接创建: 内部类名 a = new 内部类名(),不再需要先创建一个外部类再创建内部类。

package :包,是用来区分class的命名空间的。
包的目录结构用点分割,包名都是小写。

2020-06-30 01:32:04
北京 永丰

posted @ 2020-06-30 01:33  毛利小九郎  阅读(110)  评论(0编辑  收藏  举报