第4章 类和对象

Ch4 类和对象

Created on 2022/09/21 by wyq.

4.1面向对象概述

1、类

类是对象的抽象,它描述了一组具有相同属性和相同方法的一组对象的集合,类中定义
了对象所具有的属性和行为(对象的属性用变量来表示,对象的行为用方法来表示);

2、对象

对象是类的具体,它代表了某个具体的操作,一个个对象组成了完整的程序设计,对象
之间通过相互作用传递信息,(对象所拥有的特征在类中表示时称为类的属性,对象执行
的操作称为类的方法)。
PS:关于对象的几点说明
A、对象具有属性和行为;
B、对象具有变化的状态;
C、对象具有唯一性;
D、对象是某个类的实例。

3、面向对象的三大特性

A、继承:程序中的的继承是指子类拥有父类的全部属性和行为,这是类之间的一种关系。
B、封装:封装是指类中的某些信息隐藏在类的内部,不允许外部程序直接访问,只能通过
该类提供的方法来实现对隐藏信息的操作和访问。封装的目的在于阻止外部的程序随意访问
内部代码和数据。
C、多态:指同一种行为(方法)具有多种表现形态。
①编译时多态:主要指方法的重载,在编译时根据参数列表来区分不同的方法;
②运行时多态:同一类型的引用使用不同的实例而执行不同的操作,产生不同的结果;
实现方式:继承、接口

4.2 类和对象

1、类的定义


[public][abstract|final] class <class_name1> [extends <class_name2>]
[implements <interface_name>]{
    /* 类体 */
    // 类的属性
    // 类的方法
}
PS:
A、public: 使用public修饰,则可以被其他类和程序访问。每个Java程序的主类必须是public的;
B、abstract:被abstract修饰的类为抽象类,抽象类不能被实例化,抽象类中可以有抽象方法和具体方法。继承该抽象类的所有子类必须实现该抽象类中的所有抽象方法(除非子类也为抽象类);
C、final:被final修饰的类,则不允许被继承;
D、extends:表示继承其他类;
E、implements:表示实现某些接口。
e.g.
class Student{
   // 属性(用变量来表示)
   String name;
   int age;
   char gender;

   // 行为(用方法来表示)
    void eat(){
        // 方法体
        System.out.println(name+"正在吃饭!");
    }
    void study(){
        System.out.println(name+"正在学习!");
    }

}

// 主类
public class Demo1 {
    // 主方法
    public static void main(String[] args) {
        // 创建一个对象(实例)s1
        Student s1 = new Student();

        // 对s1进行初始化
        s1.name = "小明";
        s1.age = 20;
        s1.gender = '男';

        System.out.printf("姓名:%s,年龄:%d,性别:%c\n",s1.name,s1.age,s1.gender);

        // 通过对象去调用类中的方法
        s1.eat();
        s1.study();

    }
}

2、类的属性

在Java中类的成员变量定义了类的属性,声明成员变量的语法格式如下:
[public|protected|private][static][final] <type> <var_name>;
A、public、protected、private:用于表示成员变量的访问权限;
B、static:表示成员变量为静态变量(类变量);
C、final:表示将该成员变量声明为常量。
PS:如果声明成员变量时没有对其初始化,则系统会自动赋一个默认值(数值型为0, boolean类型为 false,引用类型为 null)。
e.g.
class Student{
   // 属性(用变量来表示)
   String name;
   int age;
   char gender;

   // 行为(用方法来表示)
    void eat(){
        // 方法体
        System.out.println(name+"正在吃饭!");
    }
    void study(){
        System.out.println(name+"正在学习!");
    }

}

// 主类
public class Demo1 {
    // 主方法,程序的入口
    public static void main(String[] args) {
        // 创建一个对象(实例)s1
        Student s1 = new Student();
        System.out.printf("姓名:%s,年龄:%d,性别:%c\n",s1.name,s1.age,s1.gender);

    }
}

e.g.
public class Demo2 {
    public static void main(String[] args) {
        // 创建一个具体的对象a1
        Animal a1 = new Animal();
        // 对a1进行初始化
        a1.name = "灰太狼";
        a1.age = 3;
        // 通过对象名a1调用类中的方法
        a1.eat();
        a1.run();
    }
}

class Animal{
    // 属性
    String name;
    int age;

    // 行为
    void run(){
        System.out.println(name+"正在奔跑!");
    }
    void eat(){
        System.out.println(name+"正在吃饭!");
    }
}

3、类的方法

方法是对对象的行为或功能的表示,标志了类所具有的功能和操作;类的各种功能和 操作是通过方法来实现;属性只不过提供了相应的数据。
方法的声明格式如下:
[public|protected|private] [static] <void|return_type> <method_name>([params])
e.g.
class A{
    // 计算两数之和
    protected int f1(int x, int y){
        return x+y;
    }

    // 比较两数最大值,并返回
    double f2(int x,int y){
        return x>y?x:y;
    }
}

public class Demo2 {
    public static void main(String[] args) {
        // 创建A类的一个对象 a
        A a = new A();
        int r1 = a.f1(5,10);
        double r2 = a.f2(5,10);
        System.out.println(r1);
        System.out.println(r2);
    }
}

PS:关于局部变量的几点说明:
A、在方法体内定义的变量为局部变量,它的生存期和作用域是在方法体内,离开本方法 这些变量将被自动释放;
B、在方法体内定义变量时,变量前不能加修饰符;
C、局部变量在使用前必须明确赋值;
D、在一个方法的内部,可以在复合语句中定义变量,这些变量只在复合语句中有效;

4、构造方法(构造器)

构造方法是一种特殊的方法,用来初始化类的一个对象,在创建对象(new 运算符)后自动调用。Java中每个类都有一个以上的构造方法,在定义类时没有显式定义构造方法,系统会产生一个默认的构造方法,默认构造方法没有参数,并且方法体为空,如果class是public的,则默认 构造方法也是public的。
关于构造方法的几点说明:
A、构造方法分的方法名和类名相同;
B、构造方法没有返回类型,也不能写void;
C、构造方法的作用是完成类对象的初始化操作;
D、构造方法只能用 new 来调用;
E、在创建一个类对象时,系统会自动调用该类的构造方法为新对象初始化;
e.g.
class Student{
    // 定义类的属性
    String name;
    int age;

    // 不带参数的构造方法
    Student(){
        name = "小明";
        age =19;
    }

    // 带参数的构造方法
    Student(String n,int a){
        name = n;
        age = a;
    }
}

public class Demo2 {
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.printf("%s,%d\n",s1.name,s1.age);

        Student s2 = new Student("张三",20);
        System.out.printf("%s,%d\n",s2.name,s2.age);
    }
}

5、对象的创建和使用

A、显式创建对象(使用new关键字创建对象)
类名 对象名 = new 类名();
B、隐式创建对象
e.g.
String s = "Hello Java!"
C、匿名对象
e.g.
new Student();
D、对象的使用
对象名.属性名; // 访问对象的属性
对象名.成员方法名(); // 访问对象的方法
PS:每个对象都是相互独立的,在内存中占有独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成了垃圾,被Java虚拟机 回收处理。
e.g.

public class Demo2 {
    public static void main(String[] args) {
        // 创建一个对象 s1
        Student s1 = new Student();
        System.out.printf("%s,%d\n",s1.name,s1.age);
        s1.study();
        
        // 创建一个匿名对象
        new Student("张三",18).study();
    }
}

class Student{
    // 类的属性
    String name;
    int age;

    // 无参的构造器
    Student(){
        name = "小明";
        age = 19;
        study();
    }

    // 带参数的构造器
    Student(String n,int a){
        name = n;
        age = a;
        study();
    }

    // 类的方法(实例方法)
    void study(){
        System.out.println(name+"在学习!");
    }
}

6、this的使用

(1) this 变量(表示当前对象的引用);
(2) this.属性名;
(3) this.方法名;
(4) this();
e.g.

public class Demo2 {
    public static void main(String[] args) {
        // 创建对象 s1
        Student s1 = new Student("张三",19);
        // 创建一个匿名对象
        new Student();
    }
}

class Student{
    // 类的属性
    String name;
    int age;

    Student(){
        this("小明",20);
    }

    Student(String name,int age){
        this.name = name;
        this.age = age;
        this.study();
    }

    void study(){
        System.out.println(this.name+"在学习!");
    }
}
PS:关于this使用的几点说明
A、this()只能在构造方法中使用;
B、在构造方法中使用this()时,必须是第一条语句;
C、static修饰的方法中不能使用this引用,Java中静态成员不能直接访问非静态成员。

*7、析构方法

析构方法与构造方法相反,当对象脱离其作用域时,系统自动执行析构方法来做清理垃圾工作,当创建对象时使用new 开辟了内存空间,应在退出前在析构方法中将其释放。

4.3 访问控制修饰符(权限修饰符)

信息隐藏是OOP最重要的功能之一,在编写程序时,有些核心数据不希望被用户调用,则可以通过使用访问控制修饰符来限制对象私有属性或方法的访问。
类的访问控制修饰符只能是public或者默认;对于类的成员的访问控制修饰符有4个

在这里插入图片描述

(1) private:用private修饰的成员,只能被该类中的方法访问;
(2) 默认:只能被同一个包中的类访问和引用,称为包访问特性;
(3) protected:使用protected的作用是允许其他包中的子类来 访问父类的属性和方法。
(4)public:当一个类声明为public时,它就具有了被其他包中的类访问的可能性。

4.4 非访问控制修饰符

Java中常用的非访问控制修饰符有static、final、abstract在这里插入图片描述

1、static

在类中用static修饰成员变量称为静态变量(类变量)、修饰的方法称为静态方法、他们统称为静态成员,归属于整个类,静态成员不依赖于类的实例(对象),被类的所有实例共享。
关于静态成员和非静态成员的几点说明:
A、静态(static修饰的)成员从属于类;
B、实例(非静态)成员从属于对象;
C、静态方法不能直接访问(实例)非静态成员;
(1)静态变量和实例变量的区别
静态变量可以被类的实例共享,因此静态变量可以作为实例之间的共享数据,增加实例之间的交互性。
(2)静态方法和实例方法的区别
静态方法不需要通过类的实例调用,因此在静态方法中不能使用this和super,也不能访问类 的实例成员,实例方法中可以访问静态成员和实例成员。
public class Test1 {
    // 静态变量(类变量),从属于类
    static String bj = "21物联网1班";
    // 实例变量
    String name;

    // 静态方法
    static void f1(){
        System.out.println("这是静态方法");
    }

    // 实例方法
    void f2(){
        System.out.println("这是实例方法");
        // 在实例方法中可以调用静态方法
        f1();
    }

    public static void main(String[] args) {
        // 访问类中的静态变量
        System.out.println(Test1.bj);
        System.out.println(new Test1().bj);
        // 访问类中的实例变量
        System.out.println(new Test1().name);
        // 调用静态方法f1()
        f1();
        // 在静态方法中不能直接调用实例方法f2(),只能通过该类的对象去调用
        new Test1().f2();
    }
}
(3)静态代码块和非静态代码块
static{}代码块主要用于初始化类中的静态变量,提升程序的性能;Java虚拟机在加载类时执行静态代码块,因此可以将只需要一次初始化的操作放在静态代码块中; 静态代码块中不能直接访问实例成员。非静态代码块只在创建对象的时候执行。
e.g.
public class Test1 {
    static int count =0;

    // 非静态代码块
    {
        count++;
        System.out.println("非静态代码块,count="+count);
    }

    // 静态代码块1
    static {
        count++;
        System.out.println("静态代码块1,count="+count);
    }
    // 静态代码块2
    static {
        count++;
        System.out.println("静态代码块2,count="+count);
    }
    
    public static void main(String[] args) {
        new Test1();
    }
}

PS:静态代码块随着类的加载而加载,非静态代码块只在创建对象时执行。
(4) 静态导入
用于导入类中的静态成员
import static package.ClassName.fieldName|methodName
import static package.ClassName.*
package pack1;

public class A {
    // 静态变量
    public static String s1 = "这是静态变量";
    // 实例变量
    public String s2 = "这是实例变量";
    // 静态方法
    public static void f1(){
        System.out.println("这是静态方法");
    }
    // 实例方法
    public void f2(){
        System.out.println("这是实例方法");
    }
}


// 非静态导入
import pack1.A;

// 静态导入
import static pack1.A.f1;
import static pack1.A.s1;

public class Test2 {
    public static void main(String[] args) {
        // 访问A类中的静态成员
        System.out.println(s1);
        f1();

        // 访问A类中的实例成员
        A a = new A();
        System.out.println(a.s2);
        a.f2();
    }
}

2、final

(1)fianl类
被final修饰的类不能被继承,即不可能有子类;
(2)final方法
被final修饰的方法不能被重写;
(3)final变量
被final修饰的变量即常量,必须且只能赋值一次;
关于final变量的几点说明:
A、通常用static和final一起声明一个常量;
B、在定义final局部变量时也必须且只能赋值一次;
C、final局部变量经常用于处理匿名类及Lambda表达式。

3、abstract

(1)abstract类
凡是用abstract修饰的类称为抽象类;
关于抽象类的几点说明:
A、由于抽象类是需要被继承的,因此不能是否final修饰;
B、抽象类的子类也可以是抽象类;
C、抽象类不能用new来实例化,但可以有构造方法,也可以被子类的构造方法调用;
D、抽象类中可以有抽象方法也可以有非抽象方法。
(2)abstract方法
被abstract修饰的方法称为抽象方法;
关于抽象方法的几点说明:
A、抽象方法没有方法体;
B、抽象方法只存在于抽象类中;
C、子类继承抽象类时,必须重写抽象类中的所有抽象方法;
e.g.
// 定义一个抽象类
abstract class A{
    // 抽象方法f1
    abstract void f1();
    // 抽象方法f2
    abstract String f2(String name,int age);

    // 非抽象方法f3
    static void show(){
        System.out.println("这是非抽象方法");
    }

}

public class Demo2 extends A{
    // 重写抽象类A中的抽象方法f1
    void f1(){
        System.out.println("重写抽象类中的抽象方法f1");
    }

    // 重写抽象类A中的抽象方法f2
    String f2(String name,int age){
        String s = "姓名:"+name+",年龄:"+age;
        return s;
    }

    public static void main(String[] args) {
        Demo2 d2 = new Demo2();
        d2.f1();
        d2.f2("小明",20);
        // 调用抽象类中的非抽象方法
        A.show();
    }
}

*4、其他修饰符

(1) volatil 易失
(2) native 本地
(3) synchronized 同步

4.5 包(package)

为了解决同名类的冲突问题,Java提供了包来管理命名空间;

(1)package语句

package语句应放在源文件的第一行,指明该文件中定义的类所在的包;
package pkg1[.pkg2[.pkg...]];

(2)import语句

import 语句可以向某个java文件中导入指定包下的某个类;
import pkg1[.pkg2...].ClassName|*;
import static pkg1[.pkg2...].ClassName.fieldname|methodName|*;
e.g.
package pack1.pack2;

public class A {
    // 静态常量
    public static final String S1 = "pack2中的静态字段1";
    public static final String S2 = "pack2中的静态字段2";
    // 实例常量
    public final String S3 = "pack2中的非静态字段3";
    // 静态方法f1
    public static void f1(){
        System.out.println("这是A类中静态方法f1");
    }
    // 实例方法f2
    public void f2(){
        System.out.println("这是A类中实例方法f2");
    }
}

import pack1.pack2.A;
import static pack1.pack2.A.*;
public class D {
    public static void main(String[] args) {
        // 访问A类中的静态成员
        System.out.println(S1);
        System.out.println(S2);
        f1();

        // 访问A类中的实例成员
        A a = new A();
        System.out.println(a.S3);
        a.f2();
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值