第十三篇:复习Java面向对象

一、面向对象的概念

面向对象编程(Object-Oriented Programming,OOP)是一种编程方法,其中程序是由对象组成的。面向对象的编程的核心思想是,将程序中的实体、数据和功能抽象为单独的对象,并在这些对象之间建立联系。

面向对象方法的主要方面包括:

  • 继承:子类继承父类的属性和方法,并可以添加新的属性和方法。

  • 封装:对象的内部状态和行为被隐藏在对象内部,只能通过公共的方法访问。

  • 多态:同一个方法可以有不同的实现,根据不同的对象类型而有不同的行为。

  • 抽象:通过抽象类和接口来定义对象的公共行为,但不实现该行为。

  • 关联:对象之间的关系,例如一对多,多对一等。

这些方面可以使程序更易于维护、扩展和重用,并使代码更具可读性和清晰度。面向对象的方法已经成为现代编程的重要方法,并应用于各种领域,如桌面应用程序、移动应用程序、游戏等。

二、类和对象

  • 类:是对象共同特征的描述,描述一类对象的行为和状态。
  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。

1. 如何定义/使用类

在Java当中,必须先设计类,才能获取对象。
模板如下:

public void 类名{
变量
方法
}

如何调用模板如下:

类名 对象名 = new 类名();

那么改如何创建一个对象呢?

public class Phone{
	// 属性(成员变量)
	String brand;
	double price;

	// 方法
	public void call(){
	
	}
	public void playGame(){

	}
	
}

如何得到类的对象呢?

Phone p = new Phone();

  • 调用属性:对象名.成员变量
  • 调用方法:对象名.方法()

2. 定义类的补充注意事项

  • 用来描述一类事物的类,专业叫做:javabean类,在Javabean类中,是不写main方法的

  • 而以前编写main方法的类,叫做测试类。可以在测试类中创建Javabean类的对象并进行赋值调用


  • 类名首字母大写,见名知意,小驼峰
  • 一个Java文件可以定义多个class类,且一个类只能用一个public修饰,且public修饰的类名必须成为代码文件名(实际开发中,还是一个文件定义一个类)
  • 成员变量的定义完整格式是:修饰符 数据类型 变量名 = 初始值;

三、面向对象三大特征

1. 封装

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段。

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

封装的优点:

  1. 良好的封装能够减少耦合。

  2. 类内部的结构可以自由修改。

  3. 可以对成员变量进行更精确的控制。

  4. 隐藏信息,实现细节。

1.修改属性的可见性来限制对属性的访问(一般限制为private),例如:

public class Person {
   private String name;
   private int age;
}

这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。

2.对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:

public class Person{
    private String name;
    private int age;public int getAge(){
      return age;
    }public String getName(){
      return name;
    }public void setAge(int age){
      this.age = age;
    }public void setName(String name){
      this.name = name;
    }
}

采用 this 关键字是为了解决实例变量和局部变量之间发生的同名的冲突。

实例:

/* 文件名: EncapTest.java */
public class Test{
 
   private String name;
   private String idNum;
   private int age;
 
   public int getAge(){
      return age;
   }
 
   public String getName(){
      return name;
   }
 
   public String getIdNum(){
      return idNum;
   }
 
   public void setAge( int newAge){
      age = newAge;
   }
 
   public void setName(String newName){
      name = newName;
   }
 
   public void setIdNum( String newId){
      idNum = newId;
   }
}

其实说白了就是把变量进行一次封装加密,隐藏了实现过程,提供了一个get和set方法来使用,后续可以使用注解来简化

2. 继承

2.1 例子

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

下面用父亲有两个儿子来举例:
父亲类:

public class Father extends Father{ 
	private String name;
	private int age;
	public Father(String myName,int Myage){
		name = myName;
		age = myAge;
	}

	public void eat(){
		System.out.println(name+"要吃苹果"); 
	}
	public void introduction() { 
	        System.out.println("大家好!我是"+name+"今年"+age+"岁"); 
	    } 
}

大儿子类

public class Bigson extends Father{
	 public Bigson (String myName, int myAge) { 
        super(myName, myAge); 
    } 
}

小儿子类

public class Smallson extends Father{
	 public Smallson (String myName, int myAge) { 
        super(myName, myAge); 
    } 
}

在上面代码中,Father类就是可以作为一个父类,当大儿子和二儿子继承父类后,就具有父类的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性

2.2 继承类型

java不支持多继承,但是可以多重继承,例如

  • A继承B,B继承C
  • A继承C,B继承C
  • 但是不可以 A继承B,A继承C

2.3 继承的特性

  1. 子类拥有父类非 private 的属性、方法。

  2. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  3. 子类可以用自己的方式实现父类的方法。

  4. Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

  5. 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

2.4 继承中的关键字

2.4.1 extend

在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

public class Father { 
    private String name;   
    private int age; 
    public Father (String myName, int myAge) { 
        //初始化属性值
    } 
    public void eat() {  //吃东西方法的具体实现  } 
    public void sleep() { //睡觉方法的具体实现  } 
} 
 
public class Bigson extends  Father{ 
}
2.4.2 implements

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

public interface A {
    public void eat();
    public void sleep();
}
 
public interface B {
    public void show();
}
 
public class C implements A,B {
}
2.4.3 super/this

super关键字:可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}
 
class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 调用自己的方法
    super.eat();  // super 调用父类方法
  }
}
 
public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}

输出结果:

animal : eat
dog : eat
animal : eat
2.4.4 final

final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。

final 含义为 “最终的”。

使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:

  • 声明类:
    final class 类名 {//类体}
    
  • 声明方法:
    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
    

注: final 定义的类,其中的属性、方法不是 final 的。

3. 多态

多态是同一个行为具有多个不同表现形式或形态的能力。
例如父亲与两个儿子的故事:

public void Father(){
	public void eat{
		System.out.println("我喜欢吃鸭头")}
}

public void Bigson extends Father(){
	public void eat{
		System.out.println("我喜欢吃鸭肉")}
}

public void Smallson extends Father(){
	public void eat{
		System.out.println("我喜欢吃鸭腿");
	}
}

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理

实例:

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

运行结果:
在这里插入图片描述

4. 抽象类

4.1 抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

但是说白了其实定义类的过程就是抽象和封装的过程,而抽象类与接口则是对实体类进行更高层次的抽象,仅定义公共行为和特征
在 Java 语言中使用 abstract class 来定义抽象类。如下实例:

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

4.2 抽象方法

如果一个类没有足够的信息去描述一个具体的类,那就称之为抽象类,定义一个宽泛的范围去定义,比如定义大象为动物类,动物类就是抽象类

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代码
}

声明抽象方法会造成以下两个结果

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

抽象类总结规定

    1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
    1. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
    1. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
    1. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
    1. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

四、 接口

在软件中,接口同样是一种规范和标准,它们可以约束类的行为,是一些方法特征的业合,但没有方法的实现。需要类对接口进行实现

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

1. 接口和类的异同

接口 和 类 的相同点:

  • 一个接口可以有多个方法。
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口 和 类 的不同点:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default关键字修饰的非抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多继承。

更多说明:
在这里插入图片描述

2. 抽象类和接口的区别

抽象类和接口的区别:

    1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
    1. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
    1. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
    1. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

3. 接口的声明/实现

接口的声明

  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法都是公有的。
[访问修饰符] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}

接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

public class 类名 implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...

下面举一个简单的例子:

接口的声明:

interface Animal {
   public void eat();
   public void travel();
}

接口的实现

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
 
   public void eat(){
      System.out.println("Mammal eats");
   }
 
   public void travel(){
      System.out.println("Mammal travels");
   } 
 
   public int noOfLegs(){
      return 0;
   }
 
   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

再次注意,重写接口中声明的方法时,需要注意以下规则:

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  • 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
    在实现接口的时候,也要注意一些规则:
  • 一个类可以同时实现多个接口。
  • 一个类只能继承一个类,但是能实现多个接口。
  • 一个接口能继承另一个接口,这和类之间的继承比较相似。

五、 集合框架

1. 集合与数组的区别

数组:

  1. 长度是固定的
  2. 可以存储基本数据类型,也可也存储对象的引用
  3. 对象必须是相同类型的数据

集合:

  1. 长度是可变的
  2. 只能用于存储对象的引用
  3. 对象可以是不同类型的数据

为了方便多个对象的操作,就可以将对象进行存储,集合就是存储对象最常用的一种方式。
集合框架被设计成要满足以下几个目标。

  • 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
  • 对一个集合的扩展和适应必须是简单的。

2. 集合接口

集合接口:

序号接口接口描述
1Collection 接口Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。
2List 接口List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
3SetSet 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
4SortedSet继承于Set保存有序的集合。
5MapMap 接口存储一组键值对象,提供key(键)到value(值)的映射。
6Map.Entry描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。
7SortedMap继承于 Map,使 Key 保持在升序排列。
8Enumeration这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

3. Set和List的区别

Set和List的区别

  1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。

  2. Set 检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。

  3. List 和数组类似,可以动态增长,根据实际存储的数据的长度自动增长 List 的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

4. ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口。

ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.ArrayList; // 引入 ArrayList 类

ArrayList<E> objectName =new ArrayList<>();  // 初始化
  • E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
  • objectName: 对象名。

ArrayList 类提供了很多有用的方法,常用的几个如下:
在这里插入图片描述
具体的见下表
Java ArrayList 方法
Java ArrayList 常用方法列表如下:

方法描述
add()将元素插入到指定位置的 arraylist 中
addAll()添加集合中的所有元素到 arraylist 中
clear()删除 arraylist 中的所有元素
clone()复制一份 arraylist
contains()判断元素是否在 arraylist
get()通过索引值获取 arraylist 中的元素
indexOf()返回 arraylist 中元素的索引值
removeAll()删除存在于指定集合中的 arraylist 里的所有元素
remove()删除 arraylist 里的单个元素
size()返回 arraylist 里元素数量
isEmpty()判断 arraylist 是否为空
subList()截取部分 arraylist 的元素
set()替换 arraylist 中指定索引的元素
sort()对 arraylist 元素进行排序
toArray()将 arraylist 转换为数组
toString()将 arraylist 转换为字符串
ensureCapacity()设置指定容量大小的 arraylist
lastIndexOf()返回指定元素在 arraylist 中最后一次出现的位置
retainAll()保留 arraylist 中在指定集合中也存在的那些元素
containsAll()查看 arraylist 是否包含指定集合中的所有元素
trimToSize()将 arraylist 中的容量调整为数组中的元素个数
removeRange()删除 arraylist 中指定索引之间存在的元素
replaceAll()将给定的操作内容替换掉数组中每一个元素
removeIf()删除所有满足特定条件的 arraylist 元素
forEach()遍历 arraylist 中每一个元素并执行特定操作

其他的引用类型
ArrayList 中的元素实际上是对象,数组列表元素都是字符串 String 类型。

如果要存储其他类型,而 <E> 只能为引用数据类型,这时就需要使用到基本类型的包装类。

基本类型对应的包装类表如下:

基本类型引用类型
booleanBoolean
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter

5. LinkedList

Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。

与 ArrayList 相比,LinkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低。

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

以下情况使用 LinkedList :

  • 需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

LinkedList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

// 引入 LinkedList 类
import java.util.LinkedList; 

LinkedList<E> list = new LinkedList<E>();   // 普通创建方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表

创建一个简单的链表实例:

// 引入 LinkedList 类
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
    }
}

结果如下:

[Google, Runoob, Taobao, Weibo]
方法描述
public boolean add(E e)链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public void add(int index, E element)向指定位置插入元素。
public boolean addAll(Collection c)将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。
public boolean addAll(int index, Collection c)将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。
public void addFirst(E e)元素添加到头部。
public void addLast(E e)元素添加到尾部。
public boolean offer(E e)向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public boolean offerFirst(E e)头部插入元素,返回是否成功,成功为 true,失败为 false。
public boolean offerLast(E e)尾部插入元素,返回是否成功,成功为 true,失败为 false。
public void clear()清空链表。
public E removeFirst()删除并返回第一个元素。
public E removeLast()删除并返回最后一个元素。
public boolean remove(Object o)删除某一元素,返回是否成功,成功为 true,失败为 false。
public E remove(int index)删除指定位置的元素。
public E poll()删除并返回第一个元素。
public E remove()删除并返回第一个元素。
public boolean contains(Object o)判断是否含有某一元素。
public E get(int index)返回指定位置的元素。
public E getFirst()返回第一个元素。
public E getLast()返回最后一个元素。
public int indexOf(Object o)查找指定元素从前往后第一次出现的索引。
public int lastIndexOf(Object o)查找指定元素最后一次出现的索引。
public E peek()返回第一个元素。
public E element()返回第一个元素。
public E peekFirst()返回头部元素。
public E peekLast()返回尾部元素。
public E set(int index, E element)设置指定位置的元素。
public Object clone()克隆该列表。
public Iterator descendingIterator()返回倒序迭代器。
public int size()返回链表元素个数。
public ListIterator listIterator(int index)返回从指定位置开始到末尾的迭代器。
public Object[] toArray()返回一个由链表元素组成的数组。
public T[] toArray(T[] a)返回一个由链表元素转换类型而成的数组。

六、泛型

可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。

下面是定义泛型方法的规则:

  • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的 )。
  • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
  • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
  • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。

java 中泛型标记符:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  • ? - 表示不确定的 java 类型
public class GenericMethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }
 
    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
 
        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组
 
        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组
 
        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}

运行如下:

整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O 

七、文件管理

文件和文件夹操作是常见的任务之一。可能需要读取、写入、创建、删除文件或文件夹,以及遍历文件系统中的内容。

1. 文件操作

1.1 读取文件内容

在Java中,你可以使用FileInputStreamBufferedReader来读取文件内容。以下是一个读取文本文件内容的示例:

import java.io.*;

public class ReadFileExample {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2 写入文件

要将数据写入文件,可以使用FileOutputStreamBufferedWriter,例子如下:
·

import java.io.*;

public class WriteFileExample {
    public static void main(String[] args) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
            writer.write("Hello, World!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.3 复制文件

要复制文件,可以逐个字节或块地复制文件内容。这是一个逐个字节复制文件的示例:

import java.io.*;

public class CopyFileExample {
    public static void main(String[] args) {
        try (FileInputStream inputStream = new FileInputStream("source.txt");
             FileOutputStream outputStream = new FileOutputStream("destination.txt")) {
            int byteRead;
            while ((byteRead = inputStream.read()) != -1) {
                outputStream.write(byteRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.4 移动文件

要移动文件,可以使用File类的renameTo()方法

import java.io.File;

public class MoveFileExample {
    public static void main(String[] args) {
        File sourceFile = new File("source.txt");
        File destinationFile = new File("destination.txt");
        
        if (sourceFile.renameTo(destinationFile)) {
            System.out.println("文件移动成功");
        } else {
            System.out.println("文件移动失败");
        }
    }
}

1.5 删除文件

要删除文件,可以使用File类的delete()方法。示例如下:

import java.io.File;

public class DeleteFileExample {
    public static void main(String[] args) {
        File fileToDelete = new File("fileToDelete.txt");
        
        if (fileToDelete.delete()) {
            System.out.println("文件删除成功");
        } else {
            System.out.println("文件删除失败");
        }
    }
}

2. 文件夹操作

2.1 创建文件夹

要创建文件夹,可以使用File类的mkdir()或mkdirs()方法。mkdir()只会创建一个文件夹,而mkdirs()会创建多层文件夹(如果父文件夹不存在)。示例如下:

import java.io.File;

public class CreateDirectoryExample {
    public static void main(String[] args) {
        File newDirectory = new File("newDirectory");
        
        if (newDirectory.mkdir()) {
            System.out.println("文件夹创建成功");
        } else {
            System.out.println("文件夹创建失败");
        }
    }
}

2.2 列出文件夹内容

要列出文件夹的内容,可以使用File类的list()或listFiles()方法。list()返回文件名的字符串数组,listFiles()返回File对象数组。以下是一个列出文件夹内容的示例:

import java.io.File;

public class ListFilesExample {
    public static void main(String[] args) {
        File directory = new File("myDirectory");
        File[] files = directory.listFiles();
        
        if (files != null) {
            for (File file : files) {
                System.out.println(file.getName());
            }
        }
    }
}

2.3 删除文件夹

要删除文件夹,可以使用File类的delete()方法。删除文件夹之前,必须确保文件夹为空。以下是一个删除文件夹的示例:

import java.io.File;

public class DeleteDirectoryExample {
    public static void main(String[] args) {
        File directoryToDelete = new File("directoryToDelete");
        
        if (directoryToDelete.delete()) {
            System.out.println("文件夹删除成功");
        } else {
            System.out.println("文件夹删除失败");
        }
    }
}

2.4 遍历文件夹

遍历文件夹是一种常见的任务,可以使用递归或栈来实现。以下是一个使用递归遍历文件夹的示例:

import java.io.File;

public class TraverseDirectoryExample {
    public static void main(String[] args) {
        File directory = new File("myDirectory");
        traverse(directory);
    }
    
    public static void traverse(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File subFile : files) {
                    traverse(subFile);
                }
            }
        } else {
            System.out.println(file.getName());
        }
    }
}

八、多线程

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

在这里插入图片描述

1. 线程的生命周期

在这里插入图片描述

  • 新建状态:

    使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

  • 就绪状态:

    当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

  • 运行状态:

    如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

  • 阻塞状态:

    如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:

    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。

    • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

  • 死亡状态:

    一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

2. 创建线程

创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。

为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:

public void run()

具体实例如下:

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;
   
   RunnableDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // 让线程睡眠一会
            Thread.sleep(50);
         }
      }catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}
 
public class TestThread {
 
   public static void main(String args[]) {
      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
      
      RunnableDemo R2 = new RunnableDemo( "Thread-2");
      R2.start();
   }   
}

运行如下:

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

九、小结

写本文主要是为了分享我的学习过程,也是给自己记个笔记,哪里忘记了,回来再看一眼,也可以很快的回想起来

  • 28
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
期末考试题型: 一、 填空题(本题共15空 ,每空1分,共15分。) 二、 单项选择题(本题共20小题,每题1分,共20分。) 三、 是非题(对划“√”,错划“×”,本题共10小题,每题1分,共10分。) 四、 简答题(本题共5小题,每小题5分,共25分。) 五、 程序填空题(本题共5空 ,每空2分,共10分。) 六、 编程题(本题共2小题,每小题10分,共20分。) 二、填空题 1、Java语言是一种完全的_面相对象___程序设计语言。 2、布尔型常量有两个值,它们分别是_true__、_false___。 3、在定义一个方法时,一般都要指明该方法的返回值类型,如果它不返回任何值,则必须将其声明成 void 。 4、在Java语言环境中已经包含了一组相关的核心类库,它们属于Java.lang包。 5、写出完整的main方法的声明 public static void main(String args[]) 。 6、要设计一个Applet小程序,必须先引入包 java.applet 。 7、设x=2.5,a=7,y=4.7,算术表达式x+a%3*(int)(x+y)%2/4的值为:2.75___ 8、被关键字_final___修饰的方法是不能被当前类的子类重新定义的方法。 9、Java中类成员的限定词有以下几种:private, _protected__, public__, 默认友好。 10、基类的公有成员在派生类中的访问权限由_基类___决定。 11、用static修饰的方法,称为静态方法。它们不是对象的方法,而是整个类的方法。静态方法只能处理用关键字_static___修饰的数据。 12、在Java中有一种叫作__构造方法__的特殊方法,我们在程序中用它来对类的对象成员进行初始化。 13、面向对象技术具有_封装性___、_继承性___、_抽象性___、多态性等特性。 14、Java中所有类都是类 _Object___的子类。 15、顺序执行以下两个语句的输出结果是: 10 。 String s = “我喜欢学习Java!”; System.out.println(s.length( )); 16、据程序的构成和运行环境的不同,Java源程序分为两大类: Application 程序和 Applet 程序。 17、如果一个Java源程序文件中定义有4个类,则使用Sun公司的JDK编译器javac编译该源程序文件将产生 4 个文件名与类名相同而扩展名为 class 的字节码文件。 18、开发与运行Java程序需要经过的三个主要步骤为 编辑源文件 、 编译器编译生成字节码文件 和 解释器执行 。 19、如果一个Java Applet源程序文件只定义有一个类,该类的类名为MyApplet,则类MyApplet必须是 Applet 类的子类并且存储该源程序文件的文件名必须为 MyApplet.java 。 20、 一个Java Application源程序文件名为MyJavaApplication.java,如果使用Sun公司的Java开发工具JDK编译该源程序文件并使用其虚拟机运算这个程序的字节码文件,应该顺序执行如下两个命令: javac MyJavaApplication.javajava MyJavaApplication 。 21、在Java的基本数据类型中,char型采用Unicode编码方案,每个Unicode码字符占用 2 字节内存空间,这样,无论是中文字符还是英文字符,每个都是占用2 字节内存空间。 22、在Java程序中定义的类有两种成员: 静态成员 、 实例成员 。 23、Java源程序是由类定义组成的,每个程序中可以定义若干个类,但是只有一个类是主类。在Java Application中,这个主类是指包含 main 方法的类;在Java Applet里,这个主类是一个系统类 Applet 的子类。 24、创建一个名为 MyPackage 的包的语句是 package MyPackage ; , 该语句应该放在程序的位置为: 程序中非注释行的第一行 。 25、 抽象或abstract 方法是一种仅有方法头,没有具体方法体和操作实现的方法,该方法必须在抽象类之中定义。 最终后final 方法是不能被当前类的子类重新定义的方法。 26、多态是指 一种定义,多种实现 ,在Java中有两种多态,一种是使用方法的 重载 实现多态,另一种是使用方法的 覆盖 实现多态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值