目录
6.1 面向对象概述
6.1.1 对象
对象:是事物存在的实体,eg:人类, 书桌,计算机, 高楼大厦。
对象分为两个部分被称为两个属性:
静态部分:不能动的部分
动态部分:能动的部分
图如下:
6.1.2 类
累就是同一类事物的统称,如果将现实世界中的一事物抽象成对象,类就是这类对象的统称。eg: 鸟类,家禽类,人类。类是构造对象时所依赖的规范,如一只鸟具有一对翅膀,它可以用这对翅膀飞行,而基本上所有的鸟都具有翅膀这个特性和飞行的技能,这样具有相同特性和行为的一类事物就称为类,类的思想就是这样产生的。
类是封装对象的属性和行为的载体。 如图:
定义完鸟类之后,可以根据这个类抽象出一个实体对象,最后通过这个实体对象来解决相关实际问题。
6.1.3 面向对象程序设计的特点
面向对象程序设计有以下几个特点:
封装性
继承性
多态性
1、封装:封装思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据,避免了外部操作对内部数据的影响,提高了程序的可维护性。
2、继承:类与类之间同样具有关系;eg: 一个百货公司类与销售员类相关系;
关联主要描述两个类之间的一般二元关系; eg:一个百货公司与销售员类就是一个关联,学生类与教师类也是一个关联。 两个类之间的关系有很多种,继承是关联中的一种。
3、多态:每个图形都拥有绘制自己的能力,这个能力可看作是该类具有的行为,如果将子类的对象统一看作是父亲的实例对象,这样绘制图形时,简单地调用父类也就是图形类绘制图形的方法即可绘制任何图形,这就是多态最基本的思想。
6.2 类与对象
在6.1.2节中已经讲过类是封装对象的属性和行为的载体,Java中定义类使用class关键字,其语法如下:
class 类名称{
// 类的成员变量
// 类的成员方法
}
在Java语言中对象的属性以成员变量的形式存在,对象的方法以成员方法的形式存在。本节细讲。
6.2.1 成员变量
在java中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样,语法如下:
数据类型 变量名称 [ = 值];
其中[ = 值]表示可选内容,即定义变量时可以为其赋值,也可以不为其赋值。
为了解成员变量,首先定义一个鸟类,成员变量对应于类对象的属性。
pubilc class Bird {
String wing; //翅膀
String claw; //爪子
String beak; //啄
String feather; //羽毛
}
6.2.2 成员方法
在Java语言中,成员方法对应于类对象行为,它主要用来定义类可执行的操作,它是包含一系列语言的代码块。
1、成员方法的定义
[权限修饰符 ] [ 返回值类型] 方法名 ( [ 参数类型 参数名 ] ) [ throws 异常类型 ] {
...//方法体
return 返回值 ;
}
参数可以是对象也可以是基本数据类型的变量。
定义一个showGoods方法,用来输出库存商品信息,代码如下:
pubilc viod showGoods() {
System.out.println("库存商品名称:");
System.out.println(FullName);
}
如果定义的方法有返回值,则必须使用return关键字返回一个指定类型的数据,并且返回值类型要与返回的值类型一致。
2、成员方法的参数
调用方法时可以给该方法传递一个或多个值,传给的方法的值叫做实参,在方法内部,接收实参的变量叫做形参,形参的声明语法于变量的声明语法一样。形参只在内部有效。
参数主要有3种,分别为值参数、引用参数和不定长参数。
(1)值参数
值参数表面实参与形参之间的按值传递。
public record Book() {
public static void main(String[] args) {//主函数
Book book = new Book();//创建对象
int x = 30;//定义实参变量x
int y = 40;//定义实参变量y
System.out.println("运算结果:" + book.add(x, y));//输出运算结果
System.out.println("实参x的值:"+x);//输出实参x的值
}
private int add(int x, int y)//计算两个数的和
{
x = x + y;//对x进行加y操作
return x;//返回x
}
}
(2)引用参数
如果在给方法传递参数时,参数的类型是数组或者其他引用类型那么在方法中参数的修改会反应到原有的数组或者其他引用类型上,这种类型
public class RefTest {
public static void main(String[] args) {//主函数
// TODO 自动生成的方法存根
RefTest refTest = new RefTest();//创建对象
int[] i = { 0, 1, 2 }; //定义一维数组,作为方法的实参
//输出一维数组的原始元素值
System.out.print("原始数据:");
for (int j = 0; j < i.length; j++)
{
System.out.print(i[j]+" ");
}
refTest.change(i);//调用方法改变数组元素的值
System.out.print("\n修改后的数据:");
for (int j = 0; j < i.length; j++)
{
System.out.print(i[j]+" ");
}
}
//定义一个方法,方法的参数为一维数组(形参)
public void change(int [] i)
{
i[0] = 100;
i[1] = 200;
i[2] = 300;
}
}
(3)不定长参数
声明方法时,如果有若干个相同类型的参数,可以定义为不定义参数,该类型的参数声明如下:
权限修饰符 返回值类型 方法名(参数类型... 参数名)
public class MultiTest {
public static void main(String[] args) {//主函数
// TODO 自动生成的方法存根
MultiTest multi = new MultiTest();//创建MultiTest对象
System.out.print("运算结果:" + multi.add(20, 30, 40, 50, 60));
}
int add(int... x)//定义add方法,并指定不定长参数的类型为int
{
int result = 0;//记录运算结果
for (int i = 0; i < x.length; i++)//遍历参数
{
result += x[i];//执行相加操作
}
return result;//返回运算结果
}
}
3、成员方法的使用
public class Bll {
public void gaze(String target) {// 凝视。目标是参数target
System.out.println("猎豹凝视:" + target);
}
public void run() {// 奔跑
System.out.println("猎豹开始奔跑");
}
public boolean catchPrey(String prey) {// 捕捉猎物,返回捕捉是否成功
System.out.println("猎豹开始捕捉" + prey);
return true;// 返回成功
}
public void eat(String meat) {// 吃肉,参数是肉
System.out.println("猎豹吃" + meat);
}
public void sleep() {// 睡觉
System.out.println("猎豹睡觉");
}
public static void main(String[] args) {
Bll liebao = new Bll();
liebao.gaze("羚羊");
liebao.run();
liebao.catchPrey("羚羊");
liebao.eat("羚羊肉");
liebao.sleep();
}
}
6.2.3 构造方法
构造方法的特点如下:
(1)构造方法没有返回类型,也不能定义为void。
(2)构造方法的名称要与本类的名称相同。
(3)构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员。
构造方法的定义语法如下:
class Book {
public Book() { //构造方法
}
}
class Book {
public Book() { //构造方法
}
}
public class Bll {
private Bll() {
}
// 静态公开方法,向图书馆借书
static public Bll libraryBorrow() { // 创建静态方法,返回本类实例对象
System.out.println("通过调用静态方法创建对象");
return new Bll();
}
public static void main(String[] args) {
// 创建一个书的对象,不是new实例化的,而是通过方法从图书馆借来的
Bll book = Bll.libraryBorrow();
}
}
6.2.4 局部变量
如果在成员方法内定义一个变量,那么这个变量被称为局部变量。
局部变量在方法被执行时创建,在方法执行结束时被销毁。局部变量在使用时必须进行赋值操作或者被初始化,否则会出现编译错误。
public String getName () { //定义一个getName()方法
int id=0; //局部变量
setName("Java"); //调用类中其他方法
return id+this.name; //设置方法返回值
}
6.2.5 局部变量的有效范围
可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止。
在互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。
6.2.6 对象的创建
对象可以认为是在一类事物中抽象出某一个特例,可以1通过这个特例来处理这类事物出现的问题,在Java语言中通过new操作符来创建对象。
Test test=new Test();
Test test=new Test("a");
引用只是存放一个对象的内存地址,并非存放一个对象,严格的说引用和对象是不同的,但是可以将这种区别忽略。每个对象都是对象都是相互独立的,在内存中占据独立的内存地址。
public class Bll {
public Bll () { // 构造方法
System.out.println("创建对象");
}
public static void main(String args[]) { // 主方法
new Bll (); // 创建对象
}
}
6.2.7 访问对象的属性和行为
用户使用new操作符创建一个对象后,可以使用“对象.类成员”来获取对象的属性和行为。
public class Bll {
int i = 47; // 定义成员变量
public void call() { // 定义成员方法
System.out.println("调用call()方法");
for (i = 0; i < 3; i++) {
System.out.print(i + " ");
if (i == 2) {
System.out.println("\n");
}
}
}
public Bll() { // 定义构造方法
}
public static void main(String[] args) {
Bll t1 = new Bll(); // 创建一个对象
Bll t2 = new Bll(); // 创建另一个对象
t2.i = 60; // 将类成员变量赋值为60
// 使用第一个对象调用类成员变量
System.out.println("第一个实例对象调用变量i的结果:" + t1.i);
t1.call(); // 使用第一个对象调用类成员方法
// 使用第二个对象调用类成员变量
System.out.println("第二个实例对象调用变量i的结果:" + t2.i);
t2.call(); // 使用第二个对象调用类成员方法
}
}
6.2.8 对象的销毁
每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址会被回收。
(1)对象引用超过其范围,这个对象将被视为垃圾。
(2)对象赋值为null值时将消亡。
6.2.9 this关键字
public class Bll {
String name="abc";
public void showName(String name) {
System.out.println(name);
}
public static void main(String[] args) {
Bll book = new Bll();
book.showName("123");
}
}
输出的值不是成员变量的值会导致方法无法直接使用该成员变量。
public class Bll {
String name = "abc";
public void showName(String name) {
System.out.println(this.name);
}
public static void main(String[] args) {
Bll book = new Bll();
book.showName("123");
}
}
this可以调用成员变量和成员方法但Java语言中最常规的调用方式是使用“对象.成员变量”或“对象.成员方法”进行调用。
例:在项目中创建一个类文件,在该类中定义Book类型的方法。通过this关键字进行返回
public class Book {
public Book getBook() {
return this; //返回Book类引用
}
}
public class Bll {
int eggCount;// 鸡蛋灌饼里有几个蛋
// 有参数构造方法,参数是给饼加蛋的个数
public Bll(int eggCount) {
this.eggCount = eggCount;
System.out.println("这个鸡蛋灌饼里有" + eggCount + "个蛋。");
}
// 无参数构造方法,默认给饼加一个蛋
public Bll() {
this(1);
}
public static void main(String[] args) {
Bll cake1 = new Bll();
Bll cake2 = new Bll(5);
}
}
6.3 static 关键字
static修饰的变量、常量和方法被称为静态变量、静态常量和静态方法,也被称为类的静态成员。静态成员是属于类所有的,区别于个别对象。
6.3.1 静态变量
在Java程序中,把共享的变量用static修饰,该变量就是静态变量。
语法如下:
类名.静态类成员
public class Bll {
static public int water = 0;
public void outlet() {// 放水,一次放出2个单位
if (water >= 2) {
water = water - 2;
} else {
water = 0;
}
}
public void inlet() {// 注水,一次注入3个单位
water = water + 3;
}
public static void main(String[] args) {
Bll out = new Bll();
Bll in = new Bll();
System.out.println("水池的水量:" + Bll.water);
System.out.println("水池注水两次。");
in.inlet();
in.inlet();
System.out.println("水池的水量:" + Bll.water);
System.out.println("水池放水一次。");
out.outlet();
System.out.println("水池的水量:" + Bll.water);
}
}
常见错误:同一个类的不同实例对象,共同一静态变量,如果一个类将其改变,另一个类静态变量也会更改
public class Bll {
static int x;// 静态变量
int y;// 普通成员变量
public Bll(int x, int y) {// 构造函数
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Bll a = new Bll(1, 2);
Bll b = new Bll(13, 17);
System.out.println("a.x的值是 = " + a.x);
System.out.println("a.y的值是 = " + a.y);
System.out.println("b.x的值是 = " + b.x);
System.out.println("b.y的值是 = " + b.y);
}
}
6.3.2 静态常量
用final static 修饰一个成员变量,这个成员变量就会变成一个静态常量。例如:
final static double PI = 3.1415926;
public class Bll {
final static double PI = 3.1415926;// 创建静态常量π
public static void main(String[] args) {
double radius = 3.0;// 半径
double area = Bll.PI * radius * radius;// 计算面积
double volume = 4 / 3 * Bll.PI * radius * radius * radius;// 计算体积
Circular yuan = new Circular(radius, area);
Spherical qiu = new Spherical(radius, volume);
}
}
class Circular {
double radius;// 半径
double area;// 面积
public Circular(double radius, double area) {
this.radius = radius;
this.area = area;
System.out.println("圆的半径是:" + radius + ",圆的面积是:" + area);
}
}
class Spherical {
double radius;// 半径
double volume;// 体积
public Spherical(double radius, double volume) {
this.radius = radius;
this.volume = volume;
System.out.println("球的半径是:" + radius + ",球的体积是:" + volume);
}
}
注意:给静态常量命名时所有字母都应该大写。
6.3.3 静态方法
如果想要使用类中的成员方法,需要先将这个类进行实例化,但有些时候不想或者无法创建类的对象时,还要调用类中的方法才能够完成业务逻辑,此时就可以使用静态方法。
语法如下:
类名.静态方法();
public class Bll {
static public void show() {//定义静态方法
System.out.println("静态方法无需实例化就可以调用");
}
public static void main(String[] args) {
Bll.show();//使用类名调用静态方法
}
}
6.3.4 静态代码块
在类中除成员方法之外,用static修饰代码区域可以称之为静态代码块。
语法如下:
public class StaticTest {
static {
//此处编辑执行语句
}
}
public class Bll {
static String name;
//静态代码块
static {
System.out.println(name + "静态代码块");
}
//非静态代码块
{
System.out.println(name+"非静态代码块");
}
public Bll(String a) {
name = a;
System.out.println(name + "构造方法");
}
public void method() {
System.out.println(name + "成员方法");
}
public static void main(String[] args) {
Bll s1;// 声明的时候就已经运行静态代码块了
Bll s2 = new Bll("s2");// new的时候才会运行构造方法
Bll s3 = new Bll("s3");
s3.method();//只有调用的时候才会运行
}
}
注解:
(1)静态代码块由始至终只运行了一次。
(2)非静态代码块,每次创建对象的时候会在构造方法之前运行。所以读取成员变量name时,只能获取到String类型的默认值null。
(3)构造方法只有在使用new创建对象的时候才会运行。
(4)成员方法只有在使用对象调用的时候才会运行。
6.4 类的主方法
主方法是类的入口点,它定义了程序从何处开始;主方法提供对程序流向的控制。主方法的语法如下:
public static void main(String [ ] args ) {
//方法体
}
public class Bll {
public static void main(String[] args) {
// TODO 自动生成的方法存根
for (int i = 0; i < args.length; i++) { // 根据参数个数做循环操作
System.out.println(args[i]); // 循环打印参数内容
}
}
}
在主方法的定义中可以看到主方法具有以下特性:
(1)主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须也是静态的.
(2)主方法没有返回值.
(3)主方法的形参为数组.