JavaSE学习笔记3

写在前面:

  1. Focus
  2. Keep your mind clean
  3. Beginners mind.
  4. No Ego.
  5. There is no career goal.
  6. Shut up.
  7. Mindfulness. Care. Awareness
  8. There is no Boss
  9. Do something else
  10. There is nothing special.

上一篇文章:JavaSE学习笔记2



8 类与对象

8.0 面向过程与面向对象思想

首先我们来举一个例子:
假如我们想吃饭,现在有两种方式吃到饭,一种是自己做饭吃,一种是点外卖。
我们先来看第一种方式——自己做:首先我们需要买菜,然后洗菜,再切菜,然后炒菜,最后我们就可以吃到我们自己做的菜了;
接着我们来看第二种方式——点外卖:首先我们需要点外餐,然后餐馆接收到信息后,就做菜然后让骑手送餐,最后我们就可以吃到外卖了。
我们对比下这两种方式,第一种我们每一步都需要亲自参与,所以我们扮演了一个执行者的角色;第二种我们只需要下命令,然后就会有其他人帮我们完成,我们就可以得到最后的结果,我们在其中扮演了一个指挥者的角色。

以上,执行者就是面向过程的方式,指挥者就是面向过程的方式。
面向过程
解决问题时,我们需要亲自去操作其中的每一步。
面向对象
解决问题时,我们可以借助一些工具或者事物来帮助我们,我们只关心它最后的结果。

但是回头来看,面向对象最后需要解决一个问题,也是需要有东西来解决这个问题,那最终解决这个问题的工具或事物也必然是面向过程的。
因此,面向过程与面向对象并不是独立的,而是相辅相成的。

8.1 类与对象的关系

8.1.0 什么是对象

我们常听到一句话说万物皆对象,那什么是对象呢?
对象其实就是每一件事与每一个物,比如说,一个人是一个对象,一台电脑是一个对象,一个房子是一个对象,等等。

我们可以对一个对象进行描述,比如说一个人,他有着姓名,性别,年龄,身高,体重等等,这些就是一个人的属性,这个人他能够跑步,上课,写代码这些能力,这些就是一个人的行为

这也对应这任何事物:

  • 对象的属性:就是对象的各种特征
  • 对象的行为:就是对象可以产生的动作

8.1.1 什么是类

比如说一个名叫张三的男人,一个名叫李四的女人,他们都可以统称为人,所以,这两个对象都来自于人这个

所以说,就是那些具有相同属性特征和行为的对象的统称,对象就是该类下的具体实例就相当于一个蓝图,而对象就是照着蓝图实际出来的实体

8.1.2 一个例子

定义一个圆类

class Circle {
	//数据域,也叫作类的属性,成员变量
	double radius;
	double type = 1;
	//行为,成员方法
	public double getArea() {
		return Math.PI * radius * radius;
	}
	public double getPerimeter() {
		return 2 * Math.PI * radius;
	}
	public void setRadius(double newRadius) {
		radius = newRadius;
	}
}

如何生成一个类的对象呢?

类名 变量名 = new 类名();
类名 变量名 = new 类名(参数);
//创建一个Circle对象c1
Circle c1 = new Circle();
//调用这个对象中的属性
c1.radius;
//调用这个对象中的方法
c1.getArea();

8.2 封装与private关键字

封装表面意思就是包装,将我们程序的细节包装起来,只给外界呈现它的使用方式,然后我们就可以通过它来得到结果,而不用在乎其中的细节。

封装的常见体现:

  • 方法

封装的好处:

  • 提高了安全性
  • 向外界隐藏了一些不需要外界获知的内容
  • 提高了代码复用性

封装并没有完全让外界无法访问,还是提供了相应访问内部的方法

第6章方法中曾提及过权限修饰符,这里在来探讨下。

修饰词本类同一个包的类继承类其他类
private×××
(默认)××
protected×
public

他们不仅可以修饰方法还可以修饰类和属性,我们可以先看下private修饰符,他只能在本类可访问,在其他地方都不可访问。
我们可以看下下面这个例子:

//Sample.java
public class Sample {
	Person p1 = new Person();
	p1.name = "小明";	//报错
}
class Person {
	private String name;
	private int age;
	public void speak() {
		System.out.println("我是" + name + ",今年" + age + "岁");
	}

其报错原因就是无法通过,p1.name来访问到name变量,我们在设计类的时候,通常将我们变量使用private来修饰,使其外部无法直接访问或修改其值,而这时我们将需要访问或修改的变量通过设置访问器(getXXX)或修改器(setXXX)的方法来实现。

8.3 局部变量与成员变量

我们按照的作用域可以将变量分为局部变量和成员变量,局部变量只能在声明它的方法中使用,而全局变量可以在整个类中去使用。

成员变量,在类被创建为对象时,在该对象存储空间中创建成员变量并默认初始化,在之后的该对象的任何地方都可以通过使用this来操作该对象的成员方法。

局部变量,在方法被加载入栈的时候,并执行声明语句时创建变量与变量存储空间,并在之后的方法体中可以使用该变量,直至方法结束(return),弹出栈之后,变量存储空间被回收。

区别:

声明周期存储位置定义位置初始化
成员变量与对象的生存周期相同堆中对象所属空间里在类中,在方法外默认被初始化
局部变量从声明创建开始到方法结束为止栈中方法所属空间里在方法中无默认初始化,必须先初始化后才能调用

8.4 构造器(方法)

我们在创建一个对象时是通过:类名 对象名 = new 类名();的方式,或者通过带参的方式来创建的一个对象,其实,new后面的是一个名叫构造器的方法,我们之前创建的类中可能没有给定构造器,但是也能使用无参的构造器,这是因为编译器会为无构造器的类中隐式的创建一个无参的构造器

构造器的格式

权限修饰符 类名(参数列表) {
	代码块...
}

注意:

  • 构造器没有返回值,存在返回值会被当做一个成员方法
  • 构造器的名称必须是类名
  • 构造器参数列表可为空,即无参构造器
  • 当类中没有定义显式构造器时,会为我们隐式创建无参构造器
  • 构造器只能在对象创建时被调用,构造器可以调用与之重载的构造器,但是必须在第一行使用this(..)调用,且不能产生递归调用
  • 构造器的作用主要用于对象的初始化工作

8.5 static关键字

static的作用与其本意相同,静态,它可以用于修饰方法与全局变量,注意,该修饰符不是权限修饰符,也不能修饰局部变量

static修饰方法时,该方法作为静态方法,该方法可以不用声明对象,直接通过类名.静态方法名去调用,当然也可以通过对象名.静态方法名去调用。当一个成员方法不访问成员时,可以定义为静态方法。注意,此时静态方法无法该类中的其他非静态成员,只能访问静态方法或静态变量。

static修饰成员变量时,该变量作为静态变量,该变量将不在属于某个对象独享,而是属于整个类,直接通过类名.静态变量名去调用,当然也可以通过对象名.静态变量名去调用,静态变量只会在类被装载时创建一次,之后不再创建,在程序结束时按序销毁。

8.6 静态变量与成员变量

存储位置生命周期归属调用方式
静态变量类装载的静态方法区中类的装载而创建,程序的结束而销毁整个类通过类的方式来调用,也可以通过对象的方式来调用
成员变量堆内存下对象所属空间里对象的创建而创建,对象的回收而回收单个对象只能通过对象的方式调用

9 继承

9.0 概述

9.0.0 一个例子

class Dog {
	double weight;
	double height;
	void say {
		System.out.println("Wang wang.");
	}
}
class Cat {
	double weight;
	double height;
	void say {
		System.out.println("Meow meow.");
	}
}

这里可以看出,两个类一个表示狗,一个表示猫,他们都有相同的属性,体重和身高,他们都能发声,但是发声的内容不一样,多个事物之间有共同的属性或行为,我们可以对其进行抽取,然后单独成类。

总体看,狗类与猫类他们都可以属于一个更大的类——动物类,我们可以构建一个动物类,将他们共有的属性和行为包含在里面。

class Animal {
	double weight;
	double height;
}

我们这里并没有写say()这个方法,原因是,他们在狗类与猫类中的表现是不一样的,并不能提取出来。

但是,现在这三个只是独立的类,并没有任何的联系,我们使用关键字extends来表明他们的关系。

class Animal {
	double weight;
	double height;
}
class Dog extends Animal {
	void say {
		System.out.println("Wang wang.");
	}
}
class Cat extends Animal {
	void say {
		System.out.println("Meow meow.");
	}
}

这样就可以表示他们之间的关系,总的来说,我们把多个事物的重复性的内容提取出来,生成一个新的类,这个类就是其他类的父类,也叫作基类超类,其他的类称为子类派生类,他们之间用extends关键字来标识。

9.0.1 单继承与多继承

父类与子类是一对多的关系,是一种 is a 的关系,因此,Java中类与类之间只能是单继承,但是接口与接口之间支持多继承。

class A {}
class B {}
class C extends A {}	//正确写法
class D extends A, B {}	//没有这种写法

interface E {}
interface F {}
interface G extends E {}	//正确写法
interface G extends E, F {}	//正确写法

9.0.2 继承中的特点

变量

  • 当父类中的变量被private修饰后,子类将不能直接使用父类中的变量
  • 子类中可以声明与父类相同名称的变量,两变量没有任何关系,在子类中直接访问变量名是子类中的变量,这时只有使用super关键字才能访问父类变量
    this可以表示当前对象,但是super不表示父类的对象,因此在继承中,只实例化了子类并没有实例化一个父类的对象,super只表示在子类实例化对象堆存储空间中一个表示父类的空间

方法

  • 当父类中的方法被private修饰后,子类将不能直接使用父类中的方法
  • 当子类声明与父类同名的方法,若父类方法没有被private修饰且子类中方法的权限修饰符大于或等于父类时,这里称之为重写(Override),这时也只有使用super关键字才能访问父类方法。

在程序寻找一个变量或者方法时,按照局部 → \rightarrow 对象 → \rightarrow 静态 → \rightarrow 父类

9.0.3 继承中构造器的特点

  1. 子类继承父类,子类中每一个构造器第一句如果不是this(..),那默认第一句是隐藏的super()
  2. 创建子类对象时,需要给父类中继承给子类的变量初始化
  3. 因为不能出现递归调用,所以每个构造器第一句不可能都是this(..),至少有一个super(..)
  4. 如果父类中没有无参构造器,可能会引起子类默认的super()调用失败,引发错误。建议将父类中的无参构造器显式写出来。

静态与非静态的特点一致

类的初始化过程

  1. 初始化父类中的静态成员变量和静态初始化代码块;
  2. 初始化子类中的静态成员变量和静态初始化代码块;
  3. 初始化父类的普通成员变量和初始化代码块,再执行父类的构造方法;
  4. 初始化子类的普通成员变量和初始化代码块,再执行子类的构造方法.

9.1 final

final关键字可以修饰变量,方法,类

9.1.0 修饰变量

表示该变量的值不可被修改

  • 对于基本数据类型来说,其变量存储的常量值不能被修改
  • 对于引用数据类型来说,其变量存储的对象引用不能被修改,但是可以修改对象中的数据

在类中表示一个常量用public static final 数据类型 变量名 = 常量数据;来表示,常量名应符合 常量命名法

9.1.1 修饰方法

在父类中将某方法使用final修饰,表示子类不能够进行重写(Override),但是可以调用父类的该方法

9.1.2 修饰类

表示该类不能被继承

9.2 抽象类

9.2.0 抽象方法

将多个事物的共同行为进行抽取并封装到另一个类时,但是其具体实现方法可能有所区别,但是都是做相同的事,得到相同的结果,因此,我们可以只保留方法名称,而不需要方法体,这就是抽象方法,那么这个类必须为抽象类,他们都是用abstract关键字修饰。抽象类不能创建对象,只有其实现子类能够创建对象。

9.2.1 抽象类的特点

当一个类中只要存在抽象方法,那么这个类一定是抽象类,抽象类中可以存在普通方法。一个抽象类,也可以没有抽象方法。

当一个类继承一个抽象类,如果没有实现父类中的抽象方法,就会报错。一个类如果也是抽象类,那就可以只继承另一个抽象类,且可选的去实现父类的方法。

9.2.2 abstract的非法组合

  • final:修饰类时,final表示不能被继承,但是abstract就是表示将被继承的类
  • private:修饰方法表示方法私有,不能被重写,但是abstract就是表示将被子类实现
  • static:修饰方法表示类的独占,和对象没有关系,但是abstract需要创建一个对象时,所调用的方法

9.3 接口

9.3.0 概述

接口时抽象类的一种特殊形式,当一个抽象类中的方法都是抽象方法,那么这个类就可以用接口表示。

接口不属于类,不能和类做相同的操作了,接口没有成员变量,成员方法,构造器,静态变量,静态方法。

接口不能直接创建对象。

9.3.1 定义

接口将不在用class修饰,而是使用interface修饰一个接口

interface InterfaceA {
	//这就是一个接口
}

接口中可以存在接口的“变量”与方法

  • 在接口中声明的“变量”默认会被public static final修饰,本质上为公共的静态常量
  • 在接口中声明的方法默认会被public abstract修饰,本质上是一个公共的抽象方法
  • 在接口中不能修改上述修饰符,它有且只有一种形式,只是可以省略

9.3.2 接口与类的特点

  • 接口不属于类的
  • 在类之间是单继承关系
  • 在接口之间是多继承关系
  • 在类与接口之间是实现关系,使用implements关键字表示
  • 当类为普通类时必须实现接口中的所有方法,且方法修饰符只能为public
  • 当类为抽象类时可选实现接口中的方法,且方法修饰符只能为public abstract
  • 类可以同时继承一个父类和实现多个接口

接口与抽象类区别在是否存在需要提前实现的方法


更多内容: JavaSE学习笔记1 | JavaSE学习笔记2

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值