目录
一 概念
1.1 面向过程与面向对象
面向过程:需要自己实现相关功能,以把⼤象放进冰箱为例,需要关心如何将打开冰箱,把⼤象放进冰箱,在如何把冰箱关上。这类语言以C语言为代表。
面向对象:与面向过程不同,只要对象满足要求,就不必关心其功能到底是如何实现的,只需要拿来使用即可。如小明懂得如何将大象放进冰箱,那么只需要安排小明完成任务即可,不需要关心小明如何完成任务的。Java语言就是这类面向对象的语言。
1.2 类:
类是构造对象的模板或蓝图,可以理解为制作甜点的模具,由类new出来的对象具有类的一般特性,相当于甜点。如饼干模具(类)可以做许多饼干(对象)。
1.3 对象:
对象作为类的一个实例,每个对象的状态是不同的,即每个对象都保存着描述当前状态的信息。
1.4 方法:
Java所说的方法相当于C语言的函数,用于描述一个对象的行为。Java中主要分构造方法,成员方法和静态方法。
1.5 封装:
封装,即不能让类中的方法直接访问其他类的实例字段,给对象赋予了"黑盒"特征。如果不经过方法调用就可以改变对象状态,只能说明破坏了封装性。
二 类
类的成员可以包含以下:字段 /属性/成员变量、方法、代码块、内部类
2.1 基本语法:
// 创建类
class <class_name>{
field;//成员属性
method;//成员方法
}
class : 定义类的关键字, ClassName 为类的名字, { } 中为类的主体。类中的元素称为:成员属性。类中的函数称为:成员方法。
class Person {
public int age;//成员属性 实例变量
public String name;
public String sex;
public void eat() {//成员方法
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
在上述例子中,对象的字段如果没有显式设置初始值, 那么会被设置一个默认的初值:
- 对于各种数字类型, 默认值为 0.
- 对于 boolean 类型, 默认值为 false.
- 对于引用类型(String, Array, 以及自定制类), 默认值为 null
null:
null 在 Java 中为 " 空引用 ", 表示不引用任何对象 . 类似于 C 语言中的空指针 . 如果对 null 进行 . 操作就会引发异常
2.2 static关键字:
修饰属性:
被static所修饰的数据属性称为类属性,一个类只有一份。
修饰方法:
被Static修饰的方法称为类方法。
修饰代码块:
(2.3将会介绍)
特点:不依赖于对象,我们只需要通过类名就可以调用其属性或者方法。
示例:
class TestDemo{
public int a;
public static int count;
public static void main(String[] args) {
TestDemo t1 = new TestDemo();
TestDemo t2 = new TestDemo();
t1.a++; //t1.a=1
t2.a++; //t2.a=1
TestDemo.count++; //通过类名使用属性 count=1
count++; //直接使用 count=2
}
2.3 代码块
代码块: 使用 {} 定义的一段代码
普通代码块:定义在方法中的代码块
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
}
}
构造代码块:定义在类中的代码块(不加修饰符),也叫:实例代码块。构造代码块一般用于初始化实例成员变量
示例:
class Person{
private String name;//实例成员变量
private int age;
private String sex;
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
}
}
静态代码块:使用static定义的代码块。一般用于初始化静态成员属性
示例:
class Person{
比特科技
private String name;//实例成员变量
private int age;
private String sex;
private static int count = 0;//静态成员变量 由类共享数据 方法区
//静态代码块
static {
count = 10;//只能访问静态数据成员
}
}
备注: 静态代码块优先于实例代码块执行,实例代码块优先于构造函数执行。
2.4 public 关键字
修饰class类:
表示该类为公共类,生成的文件名为public修饰的: 类名.java,一个.java文件只能有一个public类,但可以有多个非公共类。
修饰字段或方法:
表示被修饰的字段和方法是公有的,其他类都能访问该方法和修改字段。
2.5 private 关键字
主要功能: 实现封装,被修饰的方法和字段不能被其他类访问和修改,能被继承,但不能被子类使用。
封装:
- 一个私有字段
- 一个公共的字段访问器方法(返回值是引用类型的话,应当返回clone后的对象)
- 一个公共的字段更改器方法(不是必须的)
示例:
class Aa {
private int salary; //私有字段
public int getSalary() { //字段访问器方法
return salary;
}
public void setSalary(int salary) { //字段更改器方法
if (salary < 0) {
System.out.println("员工工资不能为负!");
return;
}
this.salary = salary;
}
}
public class Bb {
public static void main(String[] args) {
Aa emloyee = new Aa();
emloyee.setSalary(1000);
System.out.println("工资为:" + emloyee.getSalary()); //输出: 工资为:1000
}
}
封装优点:
1, 便于维护,修改成员字段名后,只需要修改字段访问器方法和字段更改器方法即可,不影响其他类的使用
2, 更改器方法可以完成错误检查,如员工工资不可能为负数,因此更改员工工资字段时,调用更改器方法可以完成检查。
2.6 类设计技巧
- 要保证数据私有(尽可能进行封装)
- 要对数据进行初始化
- 不要在类中使用过多基本类型(用类来替换)
- 类名和方法名要能体现它们的职责
- 优先使用不可变的类
三 对象
3.1 基本语法:
// 实例化对象
<class_name> <对象名> = new <class_name>();
示例:
public class Main{
public static void main(String[] args) {
Person person = new Person();//通过new实例化对象
Person person2 = new Person();
Person person3 = new Person();
}
}
- new 关键字用于创建一个对象的实例.
- 使用 . (点) 来访问对象中的属性和方法.
- 同一个类可以创建多个实例
- 用类类型创建对象的过程,称为类的实例化
- 类只是一个模型一样的东西,限定了类有哪些成员
- 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
- 上述例子中,person,person2都是对象。他们都是引用类型变量,相当于C语言中的指针。
3.2 this 关键字(隐式参数):
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
//this调用构造函数
this("bit", 12, "man");//必须放在第一行进行显示
}
//这两个构造函数之间的关系为重载。
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
在上述例子中,this.name 相当于类的成员变量name,区别于函数中的参数name。当形参名字和类中的成员属性的名字一样的时候,如果不使用this, 相当于自赋值。
3.3 匿名对象:
匿名只是表示没有名字的对象,即没有变量来引用对象,只能使用一次
int[] nums = new int[]{1, 2, 3};
int[] copy = Arrays.copyOf(nums, 3);
//下面的代码等价于上面的代码
int[] copy=Arrays.copyOf(new int[]{1,2,3},3);
其中,new int[] {1,2,3} 就是一个匿名对象。
3.4 对象的内存示意图:
四 方法:
4.1 成员方法
类中定义的方法,每个实例化对象都会有相同的方法:
class Person {
public int age;//成员属性 实例变量
public String name;
public String sex;
public void eat() {//成员方法
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person();//通过new实例化对象
person.eat();//成员方法调用需要通过对象的引用调用 输出:吃饭!
person.sleep(); //输出:睡觉!
}
}
在上述例子中,每个Person类的对象都有eat()和sleep()方法,使用这些方法需要使用对象来调用
4.2 构造方法
- 方法名称必须与类名称相同
- 构造方法没有返回值类型声明
- 每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
- 为对象分配内存空间
- 调用对象的构造方法
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
this.name = "caocao";
this.age = 10;
this.sex = "男";
}
//带有3个参数的构造函数
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//调用不带参数的构造函数 如果程序没有提供会调用不带参数的构造函数
p1.show(); //输出:name: caocao age: 10 sex: 男
Person p2 = new Person("zhangfei",80,"男");//调用带有3个参数的构造函数
p2.show(); //输出: name: zhangfei age: 80 sex: 男
}
}
上述例子中,Person()与Person(String name,int age,String sex) 同为构造方法,在new的时候被调用。方法名相同时,参数不同,构成方法重载,方法重载将在后面介绍
- 如果类中没有提供任何的构造函数,那么编译器会默认生成一个不带有参数的构造函数
- 若类中定义了构造方法,则默认的无参构造将不再生成.
- 构造方法支持重载. 规则和普通方法的重载一致
4.3 静态方法
class TestDemo{ public int a; public static int count; public static void change() { count = 100; //a = 10; error 不可以访问非静态数据成员 } } public class Main{ public static void main(String[] args) { TestDemo.change();//无需创建实例对象 就可以通过类调用 change() ; //直接调用 } }
- 静态方法属于类,而不属于类的对象。
- 可以直接调用静态方法,而无需创建类的实例。
- 可以用对象调用静态方法, 这是合法的,但容易混淆, 因此推荐使用类名来调用静态方法
4.4 方法重载
class Test {
public static int add(int x, int y) {
return x + y;
}
public static double add(double x, double y) {
return x + y;
}
public static double add(double x, double y, double z) {
return x + y + z;
}
}
在上述例子中:方法的名字都叫 add. 有的 add 是计算 int 相加, 有的是 double 相加; 有的计算两个数字相加, 有的是计算三个数相加.。
他们方法名相同,参数类型和个数不同构成方法的重载,在方法调用时,会根据传入参数的类型调用相应的方法。
针对同一个类 :
- 方法名相同
- 方法的参数不同(参数个数或者参数类型)
- 方法的返回值类型不影响重载
4.5 toString()方法
当我们自己输出对象时是这样:
输出bb,等价于输出bb.toString();
让我们看看toString()的原码:
默认调用的是Object的toString方法, 而Object输出的是哈西地址(所有类的都默认继承Object类)
因此,利用上述所学,我们可以重载toString方法:
class Person {
private String name;
private int age;
public Person(String name,int age) {
this.age = age;
this.name = name;
}
//重写Object的toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("毛毛",20);
System.out.println(person); //输出: Person{name='毛毛', age=20}
}
}
4.6 getter()和setter()方法
class Person {
private String name;//实例成员变量
private int age;
public void setName(String name){
//name = name; //不能这样写
this.name = name; //this引用,表示调用该方法的对象
}
public String getName(){
return name;
}
}
public static void main(String[] args) {
Person person = new Person();
person.setName("毛毛");
String name = person.getName();
}
IDEA自动生成:
首先鼠标右键:
之后选择需要构建的get与set的字段:
同理,可以自动生成toString()方法。
5 包
4.1 导入包中的类
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
4.2 将类放到包中
示例:
- 包名要和代码路径相匹配. 例如:创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存 储代码
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
- 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1 ).
- 如果一个类没有 package 语句, 则该类被放到一个默认包中
4.3 包访问权限
各修饰符访问权限图:
![](https://i-blog.csdnimg.cn/blog_migrate/5ae60160a02e2a45662481ea7d768615.png)
4.4 静态导入
Math类导入前:
public class Bb {
public static void main(String[] args) {
System.out.println(Math.PI); //输出:3.141592653589793
}
}
导入后:
import static java.lang.Math.*;
public class Bb {
public static void main(String[] args) {
System.out.println(PI); //输出:3.141592653589793
}
}
可执行jar文件
略
文档注释
略