一:java语言概述
1:java语言是一种面向对象的高级语言,由SUN公司开发。其特性包括:简单性,面向对象性,跨平台性(核心是依靠不同系统的不同JVM(java虚拟机)生成字节码文件可跨平台),安全性,支持多线程,分布式。
2:sun公司提供了一套java环境,简称JDK,JDK 中包含JRE(含有java基本类库,JVM),在JDK中存放可执行程序的目录是bin目录,存放源代码在:src.zip。
3:根据不同开发市场,将java平台分为JavaSE , JavaEE, JavaME。
4:关于字节码和源文件:java程序编写完成后(以.java结尾),然后经过命令行指令:javac 文件名.java 进行程序的编译后变为可执行文件.class ,随后由命令行指令:java 文件名 即可运行此java文件,注意此运行操作在Java虚拟机中执行。
5:在JDK中存在着bin目录文件夹,里面存放着许多可执行文件如:java.exe 用于解析.class 文件。javac.exe 用于编译java源代码。
6:想要在任何目录下都能使用java命令,需要将java命令所在的bin目录添加到path环境变量。
7:java语言包含丰富类库,提供了很多封装好的api,如果要使用需要使用import关键字进行导包
二:基本数据类型和引用数据类型(含基本数据类型的包装类,常用字符集)
基本数据类型: 对应包装类(引用数据类型)
- byte: 1 字节 (8 位) Byte
- short: 2 字节 (16 位) Short
- int: 4 字节 (32 位) Integer
- long: 8 字节 (64 位) Long
- float: 4 字节 (32 位) Float
- double: 8 字节 (64 位) Double
- char: 2 字节 (16 位,使用Unicode字符集) Character
- boolean: 1 字节 Boolean
字符集:中文在GBK 中占两个字节,在UFT-8占三个字节。
引用数据类型:Object(所有类都直接或者间继承),String 我们定义的类。
Object类的概述:是一个超类,其成员方法中常见的是下面两种
public boolean equals(Object obj) {
return (this == obj);//判断地址是否相同
}
public String toString() {//返回地址的字符串表达
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
String 类的概述:
1:String类的初始化
public class Test01 {
public static void main(String[] args) {
//方式一:在字符串常量池中创建
String s1="hello";
//方式二:在堆空间创建对象
String s2=new String("hello");
System.out.println(s1==s2);//false,==判断地址,一个在堆空间,一个在字符串常量池
}
}
2:“+”拼接字符串问题
public class Test01 {
public static void main(String[] args) {
//实现s1,s2拼接
String s1="hello";
String s2="world";
String s3 = new String("helloworld");
String s4="helloworld";
System.out.println(s1+" "+s2);//hello world
System.out.println('a'+'b');//195
System.out.println('a'+"b");//ab
System.out.println('a'+'b'+"c");//195c
System.out.println("c"+'a'+'b');//cab
System.out.println(s3==s4);//false
System.out.println(s1+s2==s3);//false
System.out.println(s1+s2==s4);//false
System.out.println(s1+"world"==s3);//false
System.out.println(s1+"world"==s4);//false
System.out.println("hello"+"world"==s4);//true
//综上变量与变量拼接=新 变量与常量拼接=新
//常量与常量=常量池中找
}
}
3:关于Sring s1="hello" 和String s2=new Sting("hello") 分别创建了多少次对象的问题:
- 字符串常量池: 当你使用双引号创建字符串时,Java 会首先检查字符串常量池中是否已经存在相同的字符串。如果存在,
s1
将引用已存在的字符串对象。如果不存在,Java 会在常量池中创建一个新的字符串对象并将其引用赋给s1
。 - 对象数量: 在这种情况下,如果程序中没有其他地方创建了
"hello"
,那么 只会创建一个对象。该对象会存储在字符串常量池中。(0个或一个) - 显式对象创建: 使用
new String()
创建的字符串始终在堆内存中创建一个新的字符串实例。即使常量池中已经有"hello"
字符串,new String("hello")
依然会在堆内存中创建一个独立的对象。 - 对象数量: 这种情况下会 创建两个对象:一个是在常量池中创建的(如果它之前不存在),另一个是使用
new
关键字在堆中创建的。
4:关于String类常用api概述:
1. 字符串长度length()
: 返回字符串的长度(字符数)
String str = "Hello";
int length = str.length(); // 5
2. 字符串比较equals(Object obj)
: 比较两个字符串的内容是否相同。
String str1 = "Hello";
String str2 = "Hello";
boolean isEqual = str1.equals(str2); // true
3. 字符串切割
substring(int beginIndex)
: 返回从指定索引到字符串末尾的子字符串。substring(int beginIndex, int endIndex)
: 返回指定范围内的子字符串(不含结束索引)。split(String regex)
: 根据正则表达式分割字符串,返回字符串数组。
4. 字符串查找
indexOf(String str)
: 返回子字符串首次出现的位置;不存在则返回 -1。lastIndexOf(String str)
: 返回子字符串最后一次出现的位置。contains(CharSequence sequence)
: 判断是否包含某个字符序列。
5. 字符串变换
toLowerCase()
: 将字符串转换为小写。toUpperCase()
: 将字符串转换为大写
三:面向对象(上)概述
1:java语言面向对象的三大特性:封装性 继承性 多态性。
2:程序中使用class 名字 关键字对一个类进行命名。主函数的入口是main,以下代码为实例。
public class Main {
public static void main(String[] args) {//程序入口,固定写法
System.out.println("helloworld");
}
}
3:类的主要成员:
属性(Fields/Variables):
- 这些是用来存储对象状态的数据。属性可以是基本数据类型(如
int
、float
、boolean
等)或者引用数据类型(如其他类的对象)。 - 示例:
public class Person { private String name; // 属性 private int age; // 属性 }
- 这些是用来存储对象状态的数据。属性可以是基本数据类型(如
方法(Methods):
- 方法定义了类的行为,是对类属性的操作和处理。方法可以有参数并返回值,也可以是无返回值的方法(
void
)。 public void setName(String name) { // 设置方法 this.name = name; // 使用this关键字引用类属性 } public String getName() { // 获取方法 return this.name; }
- 方法定义了类的行为,是对类属性的操作和处理。方法可以有参数并返回值,也可以是无返回值的方法(
构造器(Constructors):
- 构造器是一种特殊的方法,用于创建对象并初始化类的属性。它的名称与类名相同,并且没有返回值。
public Person(String name, int age) { // 构造器 this.name = name; this.age = age; }
3:构造方法的重载
public Person(String name) { // 构造器 this.name = name; }
静态成员(Static Members):
- 这些包括静态属性和静态方法,被所有实例共享。使用
static
关键字声明。 - 示例:
public static int populationCount; // 静态属性 public static void printPopulation() { // 静态方法 System.out.println("Population: " + populationCount); }
- 这些包括静态属性和静态方法,被所有实例共享。使用
内部类(Inner Classes):
- 可以在一个类中定义另一个类,称为内部类。内部类可以访问外部类的所有成员。
-
public class Outer { class Inner { // 内部类 } }
接口(Interfaces):
- 类可以实现接口,定义一组方法,但不提供实现。接口中的成员默认是
public
和abstract
。 public interface Animal { void makeSound(); // 接口方法 }
- 类可以实现接口,定义一组方法,但不提供实现。接口中的成员默认是
封装性的详解:权限修饰符排行:public>protected>默认(不填)>private
- public:对所有类可见。
- protected:对同一包内的类和子类可见。
- private:仅对定义其类可见
- 以上权限修饰可以作用在属性,方法,或者类上。
以下为封装性代码的实例:
new 关键字指代在堆内存空间中开辟一块空间返回地址给此对象。
public class Main {
//java源文件是由若干个书写形式互相独立的类组成,
// 至多只有一个类是public 修饰的类
//并且此public修饰的类必须是以此文件命名相同的(比如文件叫Main.java)
//那么要用public修饰,那么只能修饰Main类。
public static void main(String[] args) {
People p1 = new People(); //通过new关键字在堆中进行创建对象
p1.name="tom";//错误代码,因为封装性
p1.setName("tom");
System.out.println(p1.getAge());//在类里提供public权限的getter和setter方法来访问//私有变量
}
}
class People{
private String name; //private进行修饰,只能在类内直接访问
private int age=18;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;//类内直接访问
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
上述代码中出现的 this关键字作用:当方法局部变量与类内某属性的变量相同时,为了区分它们,我们使用this关键字(谁调用此方法,谁就是this所指的对象)
4:常见关键字重点概述
1. super
关键字
1:父类引用:super
用于引用当前对象的父类(超类)的属性或方法。
2:调用父类构造函数:可以通过 super()
调用父类的构造函数,必须作为子类构造函数的第一行。
3:方法重写:当子类重写父类的方法时,可以使用 super
调用被重写的方法。
2. final
关键字
1:最终变量:声明为 final
的变量一旦初始化后,其值不能再被更改。
2:最终方法:声明为 final
的方法不能被子类重写。适用于不希望被修改的方法。
3:最终类:声明为 final
的类不能被继承。这通常用于创建不可变的类。
3. static
关键字
1:静态变量:属于类而不是类的实例,所有实例共享相同的静态变量。
2:静态方法:同样属于类,可以直接通过类名调用而不需要创建对象。静态方法中不能直接访问实例变量和实例方法,只能访问其他静态成员。
3:静态块:用于初始化静态变量,在类被加载的时候执行一次。
练习:输出结果为:
我是静态代码块
我是普通代码块
空参构造器开始执行
我是普通代码块
空参构造器开始执行
18
18
结论:静态代码块属于类加载时只加载一次(加载过此类后,后续new 对象是不会再执行的)
执行顺序:静态代码块优于普通代码块(每new一次就会执行一次),普通代码块的执行顺序优于类的构造器 。
public class Main {
public static void main(String[] args) {
People people = new People();
People people1 = new People();
//调用静态变量的两种方式
System.out.println(people.age);
System.out.println(People.age);
}
}
class People{
static int age=18;
public People() {
System.out.println("空参构造器开始执行");
}
static {
System.out.println("我是静态代码块");
}
{
System.out.println("我是普通代码块");
}
}
四:面向对象(下)概述
1: 继承性(单继承特性)
以下包含关键字:extends,super,this, 以及方法重写,方法重载。
方法重写:权限修饰符,返回值类型,方法形参,方法名全部相同,不同的是方法体内容。
方法的重载:在形参列表上进行增加或是减少变量,但权限修饰符,返回值类型,方法名不变。
1. 构造方法 (Constructors):子类不能继承父类的构造方法,但可以在子类中调用父类的构造方法,用
super()
来完成。2. 静态属性和方法 (Static Attributes and Methods):子类不能继承父类的
static
属性(这些属性是与类而非实例关联的),但可以访问父类的static
属性,并且可以定义同名的属性以隐藏父类的属性。3. 私有属性和方法 (Private Attributes and Methods):子类不能直接访问父类定义的私有属性和方法。私有成员不被继承,子类只能通过父类提供的公共或受保护的方法进行访问。
4. 最终类 (Final Class):如果一个类被声明为
final
,则该类不能被继承。尝试继承一个final
类会导致编译错误。5. 最终方法 (Final Methods):如果一个方法被声明为
final
,则该方法不能在子类中被重写。虽然子类可以访问这个方法,但不能改变其实现。6. 静态内部类 (Static Inner Classes):静态内部类不可以被继承,虽可以在其他类中使用,但不能作为基类被继承。
7. 非抽象类的抽象方法 (Abstract Methods in Non-Abstract Classes):子类不能继承非抽象类中的抽象方法。只有在父类是抽象类的情况下,子类才需要实现抽象方法。
继承的简单示例:
class Father {
String name;
int age;
private double salary;//父类的私有属性
public Father(String name) {
this.name = name;
}
//构造方法重载:
public Father(String name, int age) {
this.name = name;
this.age = age;
}
/**
*一个类中默认有无参构造器(java虚拟机),如果有有参构造,则无参构造不会自动生成,需要手动添加
*/
public Father() {
System.out.println("父亲的构造器");
}
public void eat(){
System.out.println("父亲吃饭");
}
}
class Child extends Father{
public Child(String name, int age) {
super(name, age);//通过super关键字使用父类的构造器
}
public Child() {
super();
//此处使用无参构造时会首先调用父亲的无参构造
//可以省略,super()只能位于第一行
}
@Override//方法重写
public void eat() {
System.out.println("孩子吃饭");
}
}
class Test{
public static void main(String[] args) {
Child child1 = new Child();//打印处父亲的构造器
Child child2 = new Child("小明", 18);//子类继承了父类的两个属性,私有的属性不继承
System.out.println(child2.name+" "+child2.age);//借助父类有参构造子类
Father father = new Father();//父亲的构造器
father.eat();//父亲吃饭
child1.eat();//方法的重写 孩子吃饭
}
}
2:抽象类
1. 定义
抽象类是使用abstract 关键字定义的类,不能直接实例化。它可以包含抽象方法(没有实现的方法)和具体方法(有实现的方法)。抽象方法所在类一定是抽象类。
2. 特征
- 不能实例化:不能创建抽象类的实例。
- 可以包含抽象方法和具体方法:抽象方法是没有实现的方法,派生类必须实现这些方法;具体方法可以直接使用或重写。
abstract class Animal {
abstract void sound(); // 抽象方法
void eat() { // 具体方法
System.out.println("Eating...");
}
}
class Dog extends Animal {
void sound() { // 实现抽象方法
System.out.println("Bark");
}
}
3:接口
1. 定义
接口是一种引用类型,类似于类,但只能包含常量、抽象方法、默认方法和静态方法。它通过 interface
关键字定义。
2. 特征
- 不能实例化:接口本身不能被实例化。
- 只包含抽象方法和常量:在 Java 8 及之前,接口中的方法都是抽象的,不能有方法体。Java 8 引入了默认方法和静态方法,允许在接口中有具体实现。
- 支持多继承:一个类可以实现多个接口,解决了 Java 类的单继承限制问题。
3. 方法类型
- 抽象方法:没有方法体,必须被实现。
- 默认方法:使用
default
关键字定义,可以有方法体,允许在不破坏现有实现的情况下向接口添加新方法。 - 静态方法:可以在接口中定义,使用
static
关键字,可以直接通过接口调用。
4. 常量
接口中的字段是 public static final
的,等同于常量,必须在声明时初始化。调用使用 接口名.变量即可。
// 接口定义
interface Animal {
void sound(); // 抽象方法 默认是public abstract 修饰的
}
// 实现接口
class Dog implements Animal {
public void sound() { // 实现抽象方法
System.out.println("Bark");
}
}
4:接口与抽象类的区别:
- 接口只允许抽象方法和字段,而抽象类可以有构造器、字段和具体方法。
- 一个类可以实现多个接口,但只能继承一个抽象类。
- 接口更适合定义能力(行为),而抽象类更适合提供部分功能的实现。
5:多态性
1:多态存在的三个必要条件 1:继承 2:重写方法 3:父类引用指向子类对象:
Parent p = new Child();//虚方法的调用 * &&&编译看左边,执行看右边(适于方法)
对于属性则是编译运行都看左边的类型*** //
意即在继承或多态使用下,关于调用属性,看等号左边对象(子类特有访问失败)。
而关于调用方法,先看是不是子类特有(访问失败),如果不是再看等号右边的对象,先调用右边对象中的方法,若无(指只继承了没重写),则调用父类中同名的方法。
示例代码1如下:(含instanceof关键字)
public class AnimalsTset {
public static void main(String[] args) {
Animal animal=new Dog();
System.out.println(animal.name);//如果属性子父类都有,则执行结果为等号左边对象的属性值 输出animal,而不是dog
//System.out.println(animal.age);//如果属性子特有,则访问失败。
animal.eat();//发现此方法子父类都有,那么执行结果是等号右边的方法 输出狗啃骨头
//animal.watchDoor 发现此方法子类特有,调用失败,因为animal所属Animal类没有此方法
//意即在多态下是不能访问子类特有成员的 解决方法使用向下转型
if(animal instanceof Dog){//使用instanceof 关键字判断是否为Dog的实例对象
Dog dog=(Dog) animal;
//向下转型后,便可访问特有成员
//向下转型的前提必须是已发生像多态情况的向上转型
System.out.println(dog.name); // dog
dog.watchDoor(); //狗看门
}
}
}
class Animal {
String name="animal";
public void eat() {
System.out.println("动物进食");
}
public void jump() {
System.out.println("动物跳");
}
}
class Dog extends Animal{
String name="dog";
int age=10;//特有属性
public void eat(){
System.out.println("狗啃骨头");
}
public void jump() {
System.out.println("狗急跳墙");
}
/**
* 子类特有方法
*/
public void watchDoor() {
System.out.println("狗看门");
}
}
6:接口的多态和匿名内部实现类
public interface Animals {
void eat();
}
class Dogs implements Animals{
@Override
public void eat() {
System.out.println("小狗都爱吃骨头");
}
}
class Test02{
public static void main(String[] args) {
Animals animals = new Dogs();//和实例代码1大同小异
animals.eat();
//以下是内部类实现,接口不能直接new
Animals animals1=new Animals() {//假设有个小猫
@Override
public void eat() {
System.out.println("小猫吃🐟");
}
};
animals.eat();
//以下有只小鸟,匿名内部类实现方法
new Animals(){
@Override
public void eat() {
System.out.println("小鸟吃虫子");
}
}.eat();
//上述结果依次为
// 小狗都爱吃骨头
//小狗都爱吃骨头
//小鸟吃虫子
}
}