1. 面向对象的初步认识
1.1 什么是面向对象
Java是一门面对对象的语言(Object Oriented Program ,简称OOP) , 在面对对象的世界中,一切皆为对象。而面对对象是一种解决问题的思想,主要依赖与对象之间的交互来完成一件事情。
1.2 面向对象与面向过程
就拿洗衣服的例子来说:
面向过程: 注重的是洗衣服的过程,少了任意一个环节都不行
面向对象:注重的是在参与洗衣服这个过程的对象,就比如:人,衣服,洗衣粉,洗衣机。 而这个过程是通过这四个对象交互完成的,不需要关注过程如何。
2. 类的定义与使用
2.1 简单认识类
什么是类呢?
简单来说,类就是对一个实体(对象)进行描述的,主要描述该实体(对象)都有哪些属性,哪些功能 等等。
就好比 :洗衣机 它是一个品牌
属性:产品品牌,型号,重量,尺寸,颜色……
功能:洗衣,烘干,定时……
那在java中,又是如何来类的呢?
2.2 类的定义格式
定义一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类。
// 创建类
class <class_name>{
field; //成员变量,属性 --------类中,方法外
method; //成员方法
}
class为定义类的关键字,class_name为类的名字,{ }中为类的主体。
示例:定义一个People的类
class Person {
public int age; //成员属性 实例变量
public String name;
public String sex;
public void eat() { //成员方法
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
3. 类的实例化
3.1 什么是实例化
定义了一个类就相当于在计算机中定义了一个新的类型。与int , double 类似,不过 int 和 double 类型都是Java语言中内置的类型,而类则是用户自己定义了一个新的类型。他们都是类,有了这些类型之后,就可以使用这些类来定义示例
而 用类类型创建对象的过程,称为类的实例化。在Java中用 new 配合类名来实例化对象,并使用 . 来访问对象中的属性和方法。
示例:
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 person2 = new Person(); Person person3 = new Person(); } }
3.2 类和对象的说明
1. 类是一个自定义的类型,可以用来定义变量。
2. 类只是一个类似于模型的东西,用来对实体经行描述,限定了类有哪些成员。
3. 一个类可以实例化多个对象,实例化出来的对象占用实际的物理空间,用来存储类的成员变量。
4. this的引用
4.1 为什么要引用this
拿一个简单的例子来说:
我现在定义一个People的类,类中定义了一个Person(String name,int age,String sex)方法。
1. 当我们不小心把 形参 与 成员变量写成一样的时候,那么在这个函数中的name,age,sex这三个形参还是赋值给了形参(局部优先),并没有改变类中的成员变量,因此,此时加上this,就可以指明你在给name,age,sex这三个对象赋值。
2. 当多个对象同时调用一个方法时,你如何知道该方法打印的是哪个对象的数据。
就拿 public Person(String name,int age,String sex)这个方法来说,方法的参数其实是有this这个对象的,而this就指向调用这个方法的对象。--------this代表当前对象的引用
class Person {
private String name; //实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
}
//这两个构造函数之间的关系为重载。
public Person(String name,int age,String sex) {
name = name;
age = age;
sex = sex;
}
public void show() {
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person("张山",12,"男");
person.show();
}
输出 :
当 加上 this 之后:
输出 :
4.2 什么是this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问,不需要用户来传递,是由编译器自己完成的。
this 引用的是 调用该成员方法的对象。
4.3 特性
1. this 的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型。
2. this 只能在成员方法中使用。
3. 在成员方法中,this只能引用当前对象,不能再引用其他对象。
4. this 是成员方法中第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器负责将调用成员方法的对象引用传递给改成员方法,this 负责来接收。
5. 对象的构造及初始化
5.1 如何初始化对象
通过简单的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败
public static void main(String[] args){
int a;
System.out.println(a);
}
输出 : error :可能尚未初始化变量a
要想上述代码通过编译,非常简单,即在正式使用a之前,给a设置一个初始值即可。
5.2 构造方法
构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作.
new 执行过程
为对象分配内存空间
调用对象的构造方法
语法规则
1.方法名称必须与类名称相同
2.构造方法没有返回值类型声明(void 也不行)
3.每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
注意事项:
如果类中没有提供任何的构造函数,那么编译器会默认生成一个不带有参数的构造函数 若类中定义了构造方法,则默认的无参构造将不再生成. 构造方法支持重载. 规则和普通方法的重载一致.
代码示例:
class Person { private String name;//实例成员变量 private int age; private String sex; //默认构造函数 构造对象 public Person() { this.name = "lihua"; 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(); Person p2 = new Person("zhangsan",80,"男"); //调用带有3个参数的构造函数 p2.show(); } }
编译结果:
5.3 初始化
5.31 默认初始化
代码:
public class Data{
public int year;
public int month;
public int day;
……
}
此处 year,month,day并没有初始化,那为什么不像上面的a一样报未初始化的错误呢?
原来,当类中的成员变量没有初始化时,都有默认值:
5.32 就地初始化
代码示例:
public class Data{
public int year = 1999 ;
public int month = 9 ;
public int day = 9 ;
……
}
一般不建议这样写,除非有要求。
6. 封装
6.1 何为封装
面向对象程序的三大特性:封装、继承、多态。而在类和对象阶段,主要研究的是其封装啊特性。那何为封装呢?简单来讲,就是套壳屏蔽细节。
就拿计算机电脑来说,像内部的核心部件,比如主板线路如何布局,CPU如何设计等使用者并不关心,用户关心的是电脑如何开关机,如何用鼠标键盘与计算机进行交互。所以,厂家在出厂时,在外部套上壳,将内部细节隐藏起来,对外仅仅提供键盘,开关键等。
而封装,即将数据与操作数据的方法有机结合,隐藏对象属性和细节,仅对外公开与对象进行交互的接口。
6.2 访问限定符
Java中组要通过类和访问权限来实现封装:类可以将数据与封装数据的方法结合在一起,而访问权限用来控制方法或成员变量是否能直接在类外使用。
Java中提供了四种访问限定符:public private protected default
代码示例: 代码示例:
public class Person { public int age; //封装性 : 被 private 修饰的变量或方法 只能在当前类中使用 private String name; //当加了 static 时,classroom 不再是 对象 ; 属于 类的属性 ,是类所共享的 public static String classroom="101"; public Person(){ System.out.println("不带参数"); } public Person(String name, int age) { this.name = name; this.age = age; } /* // 当name 被封装后,可以通过定义类方法来进行赋值 public String getName() { return name; } public void setName(String name) { this.name = name; } */ public void sleep(){ System.out.println(this.name+"正在睡觉"); } } public class Test { public static void main01(String[] args) { //Person person=new Person("zhangshan",19); /* //当 name 和 Person 进行封装之后 ,就无法直接调用 Person person2=new Person(); person.name="张三"; */ Person per=new Person(); System.out.println(per.classroom); Person.write(); } }
当我们的对象被private修饰时,我们可以通过下面方式来编写设置或者接收成员变量的初始值:
6.3 关于包的拓展
1. 包的概念
在面向对象的体系中,提出了一个软件包的概念,即:为了更好的管理类,将多个类收集起来在一起成为一组,称为软件包。
包是对类、接口等封装机制的体现,是一种对类或者接口等的很好的组织方式。在一个工程中允许存在相同名称的类,只要在不同的包中即可。
2. 导入包中的类
Java中提供了许多现有的类供我们使用,例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的Date类。
public class Test{
public static void main(String[] args){
java.util.Date date =new java.util.Date();
……
}
上面这种写法比较麻烦,可以通过 import 语句导入包。
import java.util.Date;
public class Test{public static void main(String[] args){
Date date =new Date();
……
}
如果需要用到 java.util 中的其他类,可以用 improt java.util.*
可以用import static 导入包中的静态方法和字段:
import static java.lang.Math.*;
public class Test{public static void main(String[] args){
double x=10;
double y=30;
double result=sqrt(pow(x,2)+pow(y,2)); //可将Math.pow(x,2)简写为pow(x,2)
System.out.println(result);
}
3. 自定义包
下图就是一个简单的定义一个包的图例:
当我在这个包下建一个Test 的类:
最上面的:package com.ceshi.www 表示当前类在 com.ceshi.www 这个包中。
4.包的访问权限
包的访问权限,与上面的修饰限制符相关。
5.常见的包
java.lang:系统常用基础类(String,Object)
java.lang.reflect : java 反射编程包
java.net : 进行网络编程开发包
java.sql :进行数据库开发的支持包
java.util: java提供的工具程序包
java.io:I/O编程开发包
7. static成员
7.1 static修饰的成员变量
修饰属性,Java静态属性和类相关, 和具体的实例无关. 换句话说, 同一个类的不同实例共用同一个静态属性.
class TestDemo{ public int a; public static int count; } public class Main{ public static void main(String[] args) { TestDemo t1 = new TestDemo(); t1.a++; TestDemo.count++; System.out.println(t1.a); System.out.println(TestDemo.count); System.out.println("============"); TestDemo t2 = new TestDemo(); t2.a++; TestDemo.count++; System.out.println(t2.a); System.out.println(TestDemo.count); } }
输出:
7.2 static修饰的成员方法
如果在任何方法上应用 static 关键字,此方法称为静态方法。
1. 静态方法属于类,而不属于类的对象。
2.可以直接调用静态方法,而无需创建类的实例。
3.静态方法可以访问静态数据成员,并可以更改静态数据成员的值。
4.静态方法不能调用非静态数据成员。
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(); //无需创建实例对象 就可以调用 System.out.println(TestDemo.count); } }
输出结果:
8. 代码块
8.1 普通代码块
普通代码块(少见):定义在方法中的代码块
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 输出结果:
x1 = 10
x2 = 100
8.2 静态代码块
使用static定义的代码块。一般用于初始化静态成员属性。
class Person{ private String name;//实例成员变量 private int age; private String sex; private static int count = 0;//静态成员变量 由类共享数据 方法区 public Person(){ System.out.println("I am Person init()!"); } //静态代码块 static { count = 10;//只能访问静态数据成员 System.out.println("I am static init()!"); } 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(); Person p2 = new Person(); //静态代码块是否还会被执行? } }
注意事项:
1. 静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
2. 静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行
8.3 构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。 每构造一个对象,都会运行类中的构造代码块。
class Person{ private String name;//实例成员变量 private int age; private String sex; public Person() { System.out.println("I am Person init()!"); } //实例代码块 { this.name = "bit"; this.age = 12; this.sex = "man"; System.out.println("I am instance init()!"); } 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(); } }
// 运行结果:
I am instance init()!
I am Person init()!
name: bit age: 12 sex: man