面向对象与常用类

Java面向对象和常用类

1.类与对象、封装、构造方法

1.1面向对象思想概述

概述

Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下,

使用Java语言去设计、开发计算机程序。 这里的对象泛指现实中一切事物,每种事物都具备自己的属性行为。面

向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,描述成计算

机事件的设计思想。 它区别于面向过程思想,强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。

1.2 类和对象

什么是类

:是一组相关属性行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该

类事物。

现实中,描述一类事物:

属性:就是该事物的状态信息。

行为:就是该事物能够做什么。

举例:小猫。

属性:名字、体重、年龄、颜色。

行为:走、跑、叫。

什么是对象

对象:是一类事物的具体体现。对象是类的一个实例(对象并不是找个女朋友),必然具备该类事物的属性

和行为。

现实中,一类事物的一个实例:一只小猫。

举例:一只小猫。

属性:tom、5kg、2 years、yellow。

行为:溜墙根走、蹦跶的跑、喵喵叫。

类与对象的关系

类是对一类事物的描述,是抽象的

对象是一类事物的实例,是具体的

类是对象的模板,对象是类的实体

成员变量默认值

数据类型 默认值
基本类型 整数(byte,short,int,long) 0
浮点数(float,double) 0.0
字符(char) '\u0000'
布尔(boolean) false
引用类型 数组,类,接口 null

2.封装

2.1 封装概述

概述

面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。

封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的

方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。

原则

属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。

2.2 封装的步骤

  1. 使用 private 关键字来修饰成员变量。

  2. 对需要访问的成员变量,提供对应的一对 getXxx 方法 、 setXxx 方法。

2.3 封装的操作——private关键字

private的含义

  1. private是一个权限修饰符,代表最小权限。

  2. 可以修饰成员变量和成员方法。

  3. 被private修饰后的成员变量和成员方法,只在本类中才能访问。

封装代码实例

public class Student {
    //成员变量
    private String name;
    private int age;

    //构造方法
    public Student() {
    }

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

    //成员方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}

3. 常用类

3.1 Random类

概述:
此类的实例用于生成伪随机数。

使用实例:
使用Random类,完成生成3个10以内的随机整数的操作,代码如下:

//1. 导包
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        //2. 创建键盘录入数据的对象
        Random r = new Random();
        for (int i = 0; i < 3; i++) {
            //3. 随机生成一个数据
            int number = r.nextInt(10);
            //4. 输出数据
            System.out.println("number:" + number);
        }
    }
}

3.2 ArrayList类

概述:

是大小可变的数组的实现,存储在内的数据称为元素。此类提供一些方法来操作内部存储的元素。 ArrayList 中可不断添加元素,其大小也自动增长。

常用方法:

  • public boolean add(E e) :将指定的元素添加到此集合的尾部。
  • public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。
  • public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。
  • public int size() :返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界

特别声明:ArrayList对象不能存储基本类型,只能存储引用类型的数据。类似 <int>不能写,但是存储基本数据类型对应的 包装类型是可以的。所以,想要存储基本类型数据, <> 中的数据类型,必须转换后才能编写。

3.3 String类

概述:

String 类代表字符串。Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实

例。

类 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创建具有翻译为大写小写的所有字符的字符串的副本

特点:

  1. 字符串不变:字符串的值在创建后不能被更改。
  2. 因为String对象是不可变的,所以它们可以被共享。
  3. "abc" 等效于 char[] data={ 'a' , 'b' , 'c' } 。

构造方法:

  • public String() :初始化新创建的 String对象,以使其表示空字符序列。
  • public String(char[] value) :通过当前参数中的字符数组来构造新的String。
  • public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。

常用方法:

  • public int length () :返回此字符串的长度。
  • public String concat (String str) :将指定的字符串连接到该字符串的末尾。
  • public char charAt (int index) :返回指定索引处的 char值。
  • public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。
  • public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
  • public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。

转换功能的方法:

  • public char[] toCharArray () :将此字符串转换为新的字符数组。
  • public byte[] getBytes () :使用平台的默认字符集将该String编码转换为新的字节数组。
  • public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。

分割功能的方法:

  • public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。

3.4 static关键字

概述:

静态(static)是Java中用于定义静态成员的关键字。静态成员属于类而不是对象,可以在没有创建对象的情况下直接访问。常见的静态成员有静态变量和静态方法。

3.4.1 静态变量(类变量)

静态变量(也称为类变量)在类加载时被初始化,且只有一份副本,被所有对象共享。静态变量可以通过类名直接访问,无需创建对象。

class Circle {
    static final double PI = 3.14; // 静态变量,表示圆周率
    static int count = 0; // 静态变量,表示圆的数量

    double radius; // 普通实例变量,表示圆的半径

    Circle(double radius) {
        this.radius = radius;
        count++; // 每创建一个圆对象,静态变量count加1
    }
}

public class Main {
    public static void main(String[] args) {
        Circle c1 = new Circle(5.0);
        Circle c2 = new Circle(3.0);
        Circle c3 = new Circle(7.0);

        System.out.println("圆的数量:" + Circle.count); // 输出:圆的数量:3
        System.out.println("圆周率:" + Circle.PI); // 输出:圆周率:3.14
    }
}

3.4.2静态方法

静态方法属于类而不属于对象,可以通过类名直接调用,无需创建对象。静态方法不能访问普通实例变量,只能访问静态变量和其他静态方法。

class MathUtil {
    static int add(int a, int b) { // 静态方法,实现两数相加
        return a + b;
    }

    static int multiply(int a, int b) { // 静态方法,实现两数相乘
        return a * b;
    }
}

public class Main {
    public static void main(String[] args) {
        int sum = MathUtil.add(2, 3); // 调用静态方法add
        int product = MathUtil.multiply(4, 5); // 调用静态方法multiply

        System.out.println("2 + 3 = " + sum); // 输出:2 + 3 = 5
        System.out.println("4 * 5 = " + product); // 输出:4 * 5 = 20
    }
}

注意事项:

  • 静态方法可以直接访问类变量和静态方法。
  • 静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量或静态方法。
  • 静态方法中,不能使用this关键字。

3.5 Arrays类

在Java中,Arrays类提供了一些常用的方法用于操作数组,包括数组的排序、搜索、拷贝等操作。Arrays类中的方法都是静态方法,可以直接通过类名调用。

排序数组

Arrays类提供了sort()方法用于对数组进行排序。下面是一个示例,演示如何使用Arrays类对整型数组进行升序排序:


import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {5, 2, 8, 1, 6};
        
        System.out.println("排序前的数组:" + Arrays.toString(numbers));
        
        Arrays.sort(numbers); // 使用Arrays类的sort()方法对数组进行排序
        
        System.out.println("排序后的数组:" + Arrays.toString(numbers));
    }
}

输出:

css
排序前的数组:[5, 2, 8, 1, 6]
排序后的数组:[1, 2, 5, 6, 8]

搜索数组

Arrays类提供了binarySearch()方法用于在已排序的数组中进行二分查找。下面是一个示例,演示如何使用Arrays类在整型数组中搜索指定元素:


import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 5, 6, 8};
        int key = 5;
        
        int index = Arrays.binarySearch(numbers, key); // 使用Arrays类的binarySearch()方法在数组中搜索指定元素
        
        if (index >= 0) {
            System.out.println(key + "在数组中的索引位置为:" + index);
        } else {
            System.out.println(key + "不在数组中。");
        }
    }
}

输出:


5在数组中的索引位置为:2

拷贝数组

Arrays类提供了copyOf()方法用于拷贝数组。下面是一个示例,演示如何使用Arrays类拷贝整型数组:


import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] sourceArray = {1, 2, 3, 4, 5};
        
        int[] copyArray = Arrays.copyOf(sourceArray, sourceArray.length); // 使用Arrays类的copyOf()方法拷贝数组
        
        System.out.println("源数组:" + Arrays.toString(sourceArray));
        System.out.println("拷贝数组:" + Arrays.toString(copyArray));
    }
}

输出:

css
源数组:[1, 2, 3, 4, 5]
拷贝数组:[1, 2, 3, 4, 5]

3.6 Math类

在Java中,Math类是一个常用的数学工具类,提供了一些数学计算相关的静态方法,包括基本数学运算、三角函数、指数函数、对数函数、随机数生成等。使用Math类,我们可以方便地进行各种数学计算操作。

基本数学运算

Math类提供了一些基本的数学运算方法,如加法、减法、乘法和除法。下面是一些示例,演示如何使用Math类进行基本数学运算:

java
public class Main {
    public static void main(String[] args) {
        int a = 5;
        int b = 3;
        
        int sum = Math.addExact(a, b); // 加法
        int difference = Math.subtractExact(a, b); // 减法
        int product = Math.multiplyExact(a, b); // 乘法
        int quotient = Math.floorDiv(a, b); // 除法
        
        System.out.println("和:" + sum);
        System.out.println("差:" + difference);
        System.out.println("积:" + product);
        System.out.println("商:" + quotient);
    }
}

输出:


和:8
差:2
积:15
商:1

三角函数

Math类提供了一些三角函数的计算方法,如正弦、余弦和正切等。下面是一些示例,演示如何使用Math类进行三角函数计算:

java
public class Main {
    public static void main(String[] args) {
        double angle = 30; // 角度
        
        double sinValue = Math.sin(Math.toRadians(angle)); // 正弦
        double cosValue = Math.cos(Math.toRadians(angle)); // 余弦
        double tanValue = Math.tan(Math.toRadians(angle)); // 正切
        
        System.out.println("角度:" + angle);
        System.out.println("正弦值:" + sinValue);
        System.out.println("余弦值:" + cosValue);
        System.out.println("正切值:" + tanValue);
    }
}

输出:


角度:30.0
正弦值:0.49999999999999994
余弦值:0.8660254037844386
正切值:0.5773502691896257

指数函数和对数函数

Math类提供了一些指数函数和对数函数的计算方法,如指数、对数和平方根等。下面是一些示例,演示如何使用Math类进行指数函数和对数函数的计算:


public class Main {
    public static void main(String[] args) {
        double base = 2;
        double exponent = 3;
        
        double power = Math.pow(base, exponent); // 指数
        double logarithm = Math.log10(base); // 对数
        double squareRoot = Math.sqrt(base); // 平方根
        
        System.out.println("底数:" + base);
        System.out.println("指数:" + exponent);
        System.out.println("底数的" + exponent + "次幂:" + power); 						System.out.println("以10为底数的对数:" + logarithm); 
        System.out.println("底数的平方根:" + squareRoot); 
    } 
}

输出:

底数:2.0 
指数:3.0 
底数的3.0次幂:8.0 
以10为底数的对数:0.3010299956639812 
底数的平方根:1.4142135623730951

随机数生成

Math类提供了生成随机数的方法,可以生成不同范围的随机数。下面是一些示例,演示如何使用Math类生成随机数:


public class Main {
    public static void main(String[] args) {
        // 生成一个0到1之间的随机小数
        double randomDouble = Math.random();
        System.out.println("随机小数:" + randomDouble);
        
        // 生成一个0到10之间的随机整数
        int randomInt = (int) (Math.random() * 11);
        System.out.println("随机整数:" + randomInt);
        
        // 生成一个1到100之间的随机整数
        int randomIntInRange = (int) (Math.random() * 100) + 1;
        System.out.println("1到100之间的随机整数:" + randomIntInRange);
    }
}

输出:


随机小数:0.2579127753278349
随机整数:5
1到100之间的随机整数:64

4. 继承

继承是面向对象编程中的一个重要概念,它允许一个类继承另一个类的属性和方法,从而实现代码的复用和扩展性。在Java中,使用关键字extends来实现类的继承关系。该章将介绍继承的概念、如何在Java中使用继承以及继承的一些常用方法。

继承的概念

继承是一种面向对象编程的机制,它允许一个类从另一个类派生出子类,子类可以继承父类的属性和方法。父类也称为基类或超类,子类也称为派生类。子类可以继承父类的非私有成员变量和非私有方法,并可以在子类中添加新的成员变量和方法。

继承的概念可以用类比现实生活中的"继承"来理解。例如,一个汽车类可以继承一个交通工具类的属性和方法,从而拥有交通工具类的一些共享特性,同时也可以在汽车类中定义一些汽车独有的属性和方法。

如何在Java中使用继承

在Java中,使用extends关键字来实现类的继承关系。语法如下:

class 子类名 extends 父类名 {
    // 子类的属性和方法
}

其中,子类名表示要定义的子类的名称,父类名表示要继承的父类的名称。

例如,下面是一个简单的继承示例:

class Animal {
    void eat() {
        System.out.println("动物正在吃食物");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("狗正在汪汪叫");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 继承自Animal类的方法
        dog.bark(); // 子类自己定义的方法
    }
}

输出:


动物正在吃食物
狗正在汪汪叫

在这个示例中,Dog类继承了Animal类的属性和方法,包括eat()方法。同时,Dog类还定义了自己的方法bark()

继承的常用方法

继承使得子类可以访问父类的属性和方法,同时也可以在子类中添加新的属性和方法。除了继承父类的属性和方法外,Java还提供了一些常用的方法,用于处理继承关系中的一些特殊情况。

super关键字

super关键字在子类中用于引用父类的属性和方法。通过super关键字,子类可以调用父类的构造方法、访问父类的成员变量和调用父类的方法。例如:


class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void eat() {
        System.out.println("动物正在吃食物");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name); // 调用父类的构造方法
    }

    void bark() {
        System.out.println("狗正在汪汪叫");
    }

    void displayInfo() {
        System.out.println("狗的名字是:" + super.name); // 访问父类的成员变量
        super.eat(); // 调用父类的方法
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("旺财");
        dog.bark(); // 子类自己定义的方法
        dog.displayInfo(); // 调用子类中的方法,该方法通过super关键字访问了父类的成员变量和方法
    }
}

输出:


狗正在汪汪叫
狗的名字是:旺财
动物正在吃食物

@Override注解

在子类中重写父类的方法时,可以使用@Override注解来标注,表示这是对父类方法的重写。这样可以帮助开发者更好地理解代码,并在编译时检查是否正确地重写了父类的方法。例如:


class Animal {
    void eat() {
        System.out.println("动物正在吃食物");
    }
}

class Dog extends Animal {
    @Override
    void eat() {
        System.out.println("狗正在吃骨头");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 子类重写的方法会覆盖父类的方法
    }
}

输出:


狗正在吃骨头

final关键字

在继承关系中,final关键字可以用来修饰类、方法和成员变量。当一个类被声明为final时,它将不能被继承;当一个方法被声明为final时,它将不能被子类重写;当一个成员变量被声明为final时,它将成为常量,其值不能被修改。例如:

final class Animal { // 声明为final的类
    final String name = "动物"; // 声明为final的成员变量

    final void eat() { // 声明为final的方法
        System.out.println("动物正在吃食物");
    }
}

// 下面的Dog类将无法继承Animal类,因为Animal类被声明为final
class Dog extends Animal {  // 由于Animal类被声明为final,无法被继承,所以这里会报错
 }

class Cat extends Animal { // 由于Animal类被声明为final,无法被继承,所以这里会报错
}

public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
animal.name = "狗"; // 由于name成员变量被声明为final,无法被修改,所以这里会报错
animal.eat(); // 由于eat方法被声明为final,无法被重写,所以这里会报错
}
}

5.抽象类

抽象类是一种特殊的类,它不能被实例化,只能被继承。抽象类可以包含抽象方法,抽象方法没有具体的实现,需要在子类中进行实现。抽象类可以用来定义一些共性的行为和属性,并且可以提供一些默认的实现,但无法被直接实例化。

概述

抽象类在Java中使用abstract关键字进行声明,例如:


abstract class Animal {
    String name;
    int age;

    abstract void eat(); // 抽象方法
    abstract void sleep(); // 抽象方法

    void move() { // 普通方法
        System.out.println("动物可以移动");
    }
}

上面的代码中,Animal类是一个抽象类,包含了两个抽象方法eat()sleep(),并且还包含了一个普通方法move()。抽象类可以包含普通方法的实现,但抽象方法没有具体的实现,需要在子类中进行实现。

举例

下面以一个简单的图形类继承抽象类的例子来说明抽象类的用法:


abstract class Shape {
    abstract double getArea(); // 抽象方法
}

class Circle extends Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    double getArea() { // 实现抽象方法
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    double width;
    double height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    double getArea() { // 实现抽象方法
        return width * height;
    }
}

上面的代码中,Shape类是一个抽象类,包含了一个抽象方法getArea(),表示计算图形的面积。CircleRectangle类继承了Shape类,并且实现了getArea()方法,分别计算了圆和矩形的面积。

常用方法

抽象类的常用方法包括:

  • 定义抽象方法:使用abstract关键字进行声明,无需具体实现,子类必须实现抽象方法。
  • 定义普通方法:可以在抽象类中定义普通方法,并且可以提供默认的实现。
  • 定义成员变量:可以在抽象类中定义成员变量,并且可以被子类继承和访问。
  • 定义构造方法:抽象类可以包含构造方法,但无法被直接实例化。

6.接口

接口是一种特殊的类,它只包含抽象方法和常量,没有具体的实现。接口可以被类实现,一个类可以实现多个接口,从而具备多个接口所定义的行为。接口可以用来定义一些公共的行为规范,用于实现类的多态性和灵活性。

概述

接口在Java中使用interface关键字进行声明,例如:


interface Flyable {
    void fly(); // 抽象方法
}

interface Swimmable {
    void swim(); // 抽象方法
}

class Bird implements Flyable {
    @Override
    public void fly() { // 实现接口的抽象方法
        System.out.println("鸟儿飞翔");
    }
}

class Fish implements Swimmable {
    @Override
    public void swim() { // 实现接口的抽象方法
        System.out.println("鱼儿游泳");
    }
}

上面的代码中,FlyableSwimmable是两个接口,分别定义了飞行和游泳的行为。BirdFish类分别实现了这两个接口,并实现了接口中定义的抽象方法。

举例

下面以一个简单的汽车类实现接口的例子来说明接口的用法:


interface Driveable {
    void drive(); // 抽象方法
}

class Car implements Driveable {
    @Override
    public void drive() { // 实现接口的抽象方法
        System.out.println("汽车在驾驶");
    }
}

上面的代码中,Driveable是一个接口,定义了驾驶的行为。Car类实现了Driveable接口,并实现了接口中定义的抽象方法drive()

常用方法

接口的常用方法包括:

  • 定义抽象方法:使用abstract关键字进行声明,无需具体实现,实现类必须实现接口的所有抽象方法。
  • 定义默认方法:可以在接口中定义默认方法(使用default关键字),提供默认的实现,实现类可以直接继承或者重写。
  • 定义静态方法:可以在接口中定义静态方法(使用static关键字),可以通过接口名直接调用。
  • 定义常量:可以在接口中定义常量,常量是public static final的,可以直接访问。

总结

抽象类和接口是Java中面向对象的重要概念,用于实现类的继承、多态性和灵活性。抽象类用于定义一些共性的行为和属性,并提供默认的实现,而接口用于定义一些公共的行为规范,实现类必须实现接口的所有抽象方法。在实际的Java程序设计中,合理地使用抽象类和接口,可以使代码更加灵活、可扩展和易维护。

7.多态

多态是面向对象编程中的重要概念,它允许不同的对象对同一方法做出不同的响应。多态通过使用父类或接口类型的引用来引用不同的子类对象,从而实现了代码的灵活性和可扩展性。

概述

在Java中,多态通过继承和接口实现。例如:


class Animal {
    void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("狗叫");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("猫叫");
    }
}

上面的代码中,Animal是父类,DogCat是子类,它们都继承了Animal类。通过多态的方式,可以用Animal类型的引用来引用DogCat对象,并调用它们的makeSound()方法,会根据实际对象的类型而调用不同的方法。

举例

下面以一个简单的图形类实现多态的例子来说明多态的用法:


class Shape {
    void draw() {
        System.out.println("绘制图形");
    }
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("绘制圆形");
    }
}

class Rectangle extends Shape {
    @Override
    void draw() {
        System.out.println("绘制矩形");
    }
}

上面的代码中,Shape是父类,CircleRectangle是子类,它们都继承了Shape类。通过多态的方式,可以用Shape类型的引用来引用CircleRectangle对象,并调用它们的draw()方法,会根据实际对象的类型而调用不同的方法。

常用方法

多态的常用方法包括:

  • 方法重写:子类可以重写父类的方法,从而实现对方法的定制化实现。
  • 方法调用:通过父类或接口类型的引用,可以调用不同子类对象的同名方法,实现了方法的多态性。

8.final

final是Java中的关键字,用于修饰类、方法和变量,表示它们是不可修改的。

概述

  • 修饰类:使用final关键字修饰的类为最终类,不能被继承。
  • 修饰方法:使用final关键字修饰的方法为最终方法,不能被子类重写。
  • 修饰变量:使用final关键字修饰的变量为常量,一旦赋值后不可修改。
final class Vehicle {
    void start() {
        System.out.println("启动车辆");
    }
}

class Car extends Vehicle {
    // 编译错误,无法继承final类
}

class Bike {
    final void move() {
        System.out.println("骑行");
    }
}

class MountainBike extends Bike {
    // 编译错误,无法重写final方法
}

class Constants {
    final int MAX_VALUE = 100;
    void printMaxValue() {
        System.out.println("最大值:" + MAX_VALUE);
    }
}

class Main {
    public static void main(String[] args) {
        Constants c = new Constants();
        // c.MAX_VALUE = 200; // 编译错误,无法修改常量值
        c.printMaxValue(); // 输出:最大值:100
    }
}

9.权限

在Java中,有四种访问权限修饰符,分别是publicprivateprotected和默认(无修饰符)。它们用于控制类、方法和变量的访问范围。

概述

  • public:表示公共权限,可以在任何地方访问。
  • private:表示私有权限,只能在当前类内部访问。
  • protected:表示受保护权限,可以在当前类、同一包内和子类中访问。
  • 默认(无修饰符):表示包级权限,可以在同一包内访问。

public class Animal {
    public String name;
    private int age;
    protected double weight;
    String color;
}

10.内部类

内部类是Java中一种特殊的类,它定义在另外一个类的内部,并且可以访问外部类的成员变量和方法。内部类在Java中具有一些特殊的用途和用法,下面我们来概述一下内部类的概念、用法、举例以及常用方法的说明。

概念

内部类是在一个类的内部定义的类,它可以直接访问外部类的成员,包括私有成员,而外部类则不能直接访问内部类的成员。内部类主要分为以下几种类型:

  1. 成员内部类(Member Inner Class):定义在外部类的成员位置,可以访问外部类的成员,其实例必须依赖于外部类的实例。
  2. 静态内部类(Static Inner Class):定义在外部类的成员位置,使用static修饰,不依赖于外部类的实例,可以直接访问外部类的静态成员。
  3. 方法内部类(Local Inner Class):定义在方法内部,只能在该方法内使用。
  4. 匿名内部类(Anonymous Inner Class):没有类名,直接通过new关键字创建,通常用于创建临时的、简单的对象。

用法

内部类在Java中有多种用法,包括但不限于以下几种:

  1. 封装:内部类可以用于实现对外部类的封装,将相关的类组织在一起,提高代码的可读性和维护性。
  2. 访问外部类的私有成员:内部类可以直接访问外部类的私有成员,从而实现对私有成员的访问和操作。
  3. 实现接口:内部类可以实现外部类所实现的接口,并实现接口中的方法,从而实现多重继承的效果。
  4. 事件处理:内部类可以用于实现事件处理,将事件处理的代码封装在内部类中,从而实现事件与界面逻辑的解耦。

举例

下面我们通过一个例子来说明内部类的用法。假设我们有一个外部类 Car,它有一个成员内部类 Engine,用于表示汽车的引擎。代码如下:

public class Car {
    private String brand;
    private Engine engine;

    public Car(String brand) {
        this.brand = brand;
        this.engine = new Engine();
    }

    public void start() {
        engine.startEngine();
        System.out.println(brand + " car is started.");
    }

    private class Engine {
        public void startEngine() {
            System.out.println("Engine is started.");
        }
    }
}

在这个例子中,EngineCar 的成员内部类,可以直接访问外部类 Car 的成员变量 brand,并且在 Car 的方法 start() 中调用了 Engine 的方法 startEngine(),实现了对引擎的启动操作。

常用方法

成员内部类:

成员内部类是定义在外部类中的类,可以直接访问外部类的成员变量和方法。下面是一个示例:


public class Outer {
    private int num;

    public void display() {
        // 成员内部类的实现
        class Inner {
            void print() {
                System.out.println("Num: " + num);
            }
        }

        Inner inner = new Inner();
        inner.print();
    }
}

在这个例子中,InnerOuter 的成员内部类,可以访问 Outer 类中的私有成员变量 num

方法内部类:

方法内部类是定义在方法内部的类,只在方法内部有效。下面是一个示例:


public class Outer {
    public void display() {
        int num = 10;

        // 局部内部类的实现
        class Inner {
            void print() {
                System.out.println("Num: " + num);
            }
        }

        Inner inner = new Inner();
        inner.print();
    }
}

在这个例子中,Innerdisplay 方法内部的局部内部类,可以访问 display 方法内部的局部变量 num

静态内部类:

静态内部类是定义在外部类中的静态类,不依赖于外部类的实例,可以直接访问外部类的静态成员变量和方法。下面是一个示例:


public class Outer {
    private static int num;

    public static void display() {
        // 静态内部类的实现
        static class Inner {
            void print() {
                System.out.println("Num: " + num);
            }
        }

        Inner inner = new Inner();
        inner.print();
    }
}

在这个例子中,InnerOuter 的静态内部类,可以访问 Outer 类中的私有静态成员变量 num

匿名内部类:

匿名内部类是在声明的同时定义并创建一个类的对象,通常用于实现接口或者抽象类的实例化。下面是一个示例:


public class Outer {
    public void display() {
        // 匿名内部类的实现
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Running...");
            }
        };
        
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

在这个例子中,我们通过匿名内部类实现了 Runnable 接口的实例化,并在 display 方法中创建了一个新的线程并启动。这

posted @   RookieMaster  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示