面向对象
一,类 (一个java文件中只能有一个public修饰的class类) (JavaBean)
定义: 一切具有相似事物的称。可以描述一类事物(对象)的共同特征(属性 变量)和行为(方法)
特征:一类事物的属性,一类事物必须要有的属性
行为: 动作,一类事物的行为
public class 类名(){ 定义属性(成员变量); 写行为(成员方法); 构造器; 代码块; 内部类; }
成员变量的定义格式:
修饰符 数据类型 变量名 = 初始化值; //一般无需初始化值,因为有默认值
二,对象
定义 : 具体的事物,实体,将类实体表现出来的具体的某一个事物
创建对象 (在main主函数里): 通过类创建对象(实例化对象),对属性进行赋值,对方法进行调用
类名 对象名 = new 类名();
使用对象属性和方法
对象名.成员变量名 = 值; //调用属性(成员变量) 对象名.成员方法; //调用对象行为(成员方法)
三,一个java文件中可以有多个类,但只能有一个pubilc修饰的类(公共类)
四,构造方法 (无void)
- 构造方法是在创建对象时用来初始化成员变量的
- 构造方法必须写在实体类里,也就是不带有main主函数的类里
1.无参构造方法
创建对象依靠类中的构造方法,不创建时,JVM会默认创建一个无参构造方法,在创建对象时会默认调用无参构造方法
格式
public 类名(){ 语句体; }
2.有参构造
当创建有参构造时,不会默认创建无参构造
格式
public 类名(数据类型 参数名1,数据类型 参数名2,……){ 语句体; }
this 关键字,当前对象
五,对象的内存分析【了解】
Jvm内存分配
区域 | 作用 |
---|---|
寄存区 | 给cpu使用的,跟开发没关系 |
本地方法栈 | Jvm在执行操作系统的时候会使用,跟我们没关系 |
本地方法栈 | 存储的都时字节码.class文件 |
堆 | new创建的都在这里面 |
栈 | 存储八大基本数据类型,和(引用数据类型/对象)的地址值(16进制形式) |
六,构造代码块【了解】【看懂源码】
class Dog{
// 构造代码块
{
System.out.println("sadlkj")
}
//构造方法
public Dog(){
this.name = "大黄";
}
}
public class Dog_test{
public static void main(String[] args){
//只要创建对象就会打印构造代码块
Dog dog = new Dog();
System.out.println(dog.name);//打印 sadlkj 大黄
}
}
七,成员变量和局部变量
1. 局部变量
方法的作用域问题,局部变量只能被同区域的平级或者下一级使用
使用时需要赋值
2.成员变量
在类里面创建的,在整个类里使用
使用时不赋值时,会使用数据类型的默认值
3.区别
区别位置 | 成员变量 | 局部变量 |
---|---|---|
定位位置 | 类的大括号后面的 也叫属性 | 定义在方法体中 |
作用 | 描述一类对象的属性(特征) | 在方法体内保存变量的值 |
初始化的值 | 有默认初始值 | 没有默认值,在使用时要赋值 |
作用域 | 作用整个类 | 只能在当前方法中使用 |
内存位置 | 堆内存 | 栈内存 |
八,封装【🔺🔺🔺 重点】
Java面向对象的三大特征之一,把对象的属性和操作(服务)结合起来百年城一个整体,并尽可能地去隐藏一部分信息
Java封装 对属性的封装 ,对方法的封装,对类的封装
private 私有的 只能在自己类中调用
set方法,对private修饰的变量进行赋值
get方法,把通过set得到的值return出去
对象代表什么就封装什么数据,并且提供数据对应的行为(方法)
九,权限修饰符
作用:控制成员能被访问的范围
可以修饰类,方法和变量
- private : 修饰的变量只有在本类中使用
- 空着不写 : 能在同一个包里使用,同一个包里的其他类也能使用
- protected : 修饰的变量和方法,在同一个类中能用,在同一个包的其他类能使用,在不同包下的子类也能使用
- public : 在哪里等能使用 (公共类)
十,String字符串
字符串不能发生改变,其对象在创建后不能被更改
创建String对象的两种方式:
public class StringDemo{ public static void main(String[] args){ // 直接创建 String s1 = "abc"; // 使用 new 的方式 String s2 = new String("abcd"); System.out.println(s2); //abcd //使用char[] 创建 char[] chs = {'a','b','c','d','e','f'}; String s3 = new String(chs); System.out.println(s3);// abcdef //传递一个字节数组 byte[] bytes = {97,98,99}; String s4 = new String(bytes); System.out.println(s4); } }
- 字符串在内存中的存储:
1.当使用双引号直接赋值时,系统会检查该字符串在串池(字符串池)中是否存在 不存在时,创建新的 存在,复用老的 String s1 = "abc"; String s2 = "abc"; //两个字符串公用一个内存地址 2.当new创建字符串时,系统会在堆中创建字符串,两个值相同,地址值不同 String s3 = new String("abc"); String s4 = new String("abc"); // s3!=s4 ,地址值不同
- 字符串的比较
1.直接赋值的两个字符串比较,可以直接比较,结果为true String s1 = "abc"; String s2 = "abc"; //两个字符串公用一个内存地址 2.new出的两个比较,比较的是地址值,地址值不同,结果为false String s3 = new String("abc"); String s4 = new String("abc"); // s3!=s4 ,地址值不同 3.new创建的和直接赋值的字符串比较,直接比较,地址值不同为false String s5 = "asd"; String s6 = new String("asd"); //直接比较不相同,比较的是地址值 4.值的比较,equals boolean result1 = s1.equals(s3); // 结果为true ,直接比较值 5.equalsIgnoreCase 忽略大小写(英文状态下的)区别的值的比较,用于验证码 String s7 = new String("ABc"); boolean rasult2 = s1.equalsIgnoreCase(s7); //结果为true, 忽略大小写不同
- Scanner 输入的字符串 (在堆内存里)
Scanner sc = new Scanner(System.in); String s8 = sc.next(); System.out.println(s8==s1); System.out.println(s8==s3); // 输入的不是直接赋值的,是在堆里面重新开辟的空间
- 遍历字符串 charAt()
String str = new String("asdfghj"); str.charAt(索引);
StringBuilder : 提高字符串效率
StringBuilder sb = new StringBuilder("abc"); 1.添加元素 sb.append(任意类型); 2.反转字符串 sb.reverse(); 3.获取字符串长度 sb.length(); 4.变回字符串 sb.toString();
十一,集合
集合的长度是可变的,自动扩容
集合不能存基本数据类型
存基本数据类型时,需要将其变成对应的包装类
ArrayList<引用数据类型> list = new Arraylist<>();
集合的数据改变方式:
(1) 增(添加元素):
list.add(数据); //不管添加什么都会成功
(2) 删(删除原素): 删除索引返回被删除值,删除值返回true或false
list.remove(元素或索引); //当元素不存在时删除失败
(3) 改(修改数据):
list.set(索引值,数据值);
(4) 查(查找数据): size() 集合的长度
//查询单个数据 list.get(索引); //遍历查询 for(int i = 0 ; i < list.size();i++){ list.get(i); }
十二,static静态的 [🔺🔺🔺 重要]
12.1 概念
static 静态的 (对象可以使用,但是和对象没有关系)
12.2 静态(static)在Java中的使用
static 修饰成员变量 (静态变量)
语法格式:
static 数据类型 变量名;
在main主函数中使用:
类名.静态变量 = 值;
注意事项:
- 使用static修饰的成员变量叫静态变量
- 代码静态变量可以被类中的所有实例共享
- 静态的方法不能调用非静态的
示例:
public class StaticVar { public static String str1 = "Hello"; public static void main(String[] args) { String str2 = "World!"; // 直接访问str1 String accessVar1 = str1+str2; System.out.println("第 1 次访问静态变量,结果为:"+accessVar1); // 通过类名访问str1 String accessVar2 = StaticVar.str1+str2; System.out.println("第 2 次访问静态变量,结果为:"+accessVar2); // 通过对象svt1访问str1 StaticVar svt1 = new StaticVar(); svt1.str1 = svt1.str1+str2; String accessVar3 = svt1.str1; System.out.println("第3次访向静态变量,结果为:"+accessVar3); // 通过对象svt2访问str1 StaticVar svt2 = new StaticVar(); String accessVar4 = svt2.str1+str2; System.out.println("第 4 次访问静态变量,结果为:"+accessVar4); } }
静态方法 被static修饰的成员方法
- 静态方法不通过任何实例就可以调用,因此方法内不可以使用this关键字,且super也与对象的实例化有关,所以也不能使用
- 在实例方法(没有被static修饰的方法)中可以直接访问静态方法,静态变量
示例:
public class StaticMethod { public static int count = 1; // 定义静态变量count public int method1() { // 实例方法method1 count++; // 访问静态变量count并赋值 System.out.println("在静态方法 method1()中的 count="+count); // 打印count return count; } public static int method2() { // 静态方法method2 count += count; // 访问静态变量count并赋值 System.out.println("在静态方法 method2()中的 count="+count); // 打印count return count; } public static void PrintCount() { // 静态方法PrintCount count += 2; System.out.println("在静态方法 PrintCount()中的 count="+count); // 打印count } public static void main(String[] args) { StaticMethod sft = new StaticMethod(); // 通过实例对象调用实例方法 System.out.println("method1() 方法返回值 intro1="+sft.method1()); // 直接调用静态方法 System.out.println("method2() 方法返回值 intro1="+method2()); // 通过类名调用静态方法,打印 count StaticMethod.PrintCount(); } }
注: 在访问非静态方法时,需要通过实例对象来访问,而在访问静态方法时,可以直接访问,也可以通过类名来访问,还可以通过实例化对象来访问。
静态代码块 static{} 代码块
作用: 主要用于初始化类,为类的静态变量赋初始值,提升程序性能
格式:
static { 语句体; }
注意事项:
1.静态代码块不可以存在任何一个方法体中 2.静态代码快可以在类的任何地方,一个类中可以有多个静态代码快 3.一个方法中可以有多个静态代码快,在执行时按照顺序执行,每个只执行一次 4.静态代码块会先执行,(有时候会将只执行一次的初始化操作方法静态代码快中) 5.静态代码块和静态方法中不能直接访问实例方法和实例变量,需要通过实例对象(this)来访问
示例:
public class StaticCode { public static int count = 0; { count++; System.out.println("非静态代码块 count=" + count); } static { count++; System.out.println("静态代码块1 count=" + count); } static { count++; System.out.println("静态代码块2 count=" + count); } public static void main(String[] args) { System.out.println("*************** StaticCode1 执行 ***************"); StaticCode sct1 = new StaticCode(); System.out.println("*************** StaticCode2 执行 ***************"); StaticCode sct2 = new StaticCode(); } }
十三,继承
目的: 减少代码复用率
格式:
public class Student extends Person{ } 1.Student 称为子类或派生类 2.Person 称为父类,基类或超类
使用条件: 类和类之间存在共性的内容,并满足子类是父类中的一种
继承的特点:
1.Java只能单继承,可以多重继承 2.不写继承,默认继承Object类 3.父类的构造方法不能被子类继承 4.praviate修饰的**成员变量**可以被继承,但是只能使用get,set方法调用赋值 5.praviate修饰的**成员方法**不能被继承 6.虚方法表里的可以被继承,其他的不能 7.创建构造方法会调用父类的,默认调用无参构造
注:虚方法表 : 方法中不被praviate,final,static修饰的方法
this 关键字
定义:表示当前对象
souper 关键字
定义:表示当前类的父类
十四,方法的重写
@Override 检查重写是否正确
目的:当父类方法不能满足子类需求时,就要用到重写
本质就是对继承过来虚方法表中的方法的覆盖
要求:
1.重写的方法名,参数列表必须一致 2.子类重写父类的方法时,访问权限不能低于父类被重写的方法 3.尽量与父类保持一致 4.不在虚方法表中的方法不能被重写
十五,多态
定义:同类型的行为,对不同的对象有不同的表现形式
核心:父类的引用指向子类的对象
调用成员变量时:编译运行都看左边
调用成员方法时:编译看左边,运行看右边
向上转型: 只能调用子类中父类被重写的功能
class Animal{ public void eat(Pet pet){ pet.eat(); } } class Pet{ public void eat(){ System.out.println("吃"); } } class Dog extends Pet{ @Override public void eat() { System.out.println("吃狗粮"); } } class Cat extends Pet{ @Override public void eat() { System.out.println("吃猫粮"); } } public class Demo01 { public static void main(String[] args) { Pet dog = new Dog(); Pet cat = new Cat(); Animal animal = new Animal(); animal.eat(dog); animal.eat(cat); } }
向下转型: (把创建的父类引用强转为子类) 用于调用子类的特有功能
Dog dog1 = (Dog)dog;
十六,instanceof
判断 A 是否为 B 的对象或子类
A instanceof B
十七, 包/final
导包,创建包
包名的的规则:[公司域名反写]+包的作用 ,全部小写
- 使用同一包中的类,不需要导包
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导包
- 如果两个包的同名类,需要用全类名 (包名+类的作用)
final关键字 (可以修饰类,方法,变量)
修饰方法
不能被子类重写可以被继承
修饰方法
不能被继承
修饰变量
修饰基本数据类型不能被改变,为常量,使用时要赋值
修饰引用数据类型地址值不能被改变
十八, 代码块
局部代码块
作用: 节约代码运行内存
public static void main(Strin[] args){ { int a = 10; System.out.println(a); } //在代码块外部不能获取a }
静态代码快
特点: 只执行一次,随着类的加载而加载,避免浪费内存空间
作用: 在程序刚开始时实现数据初始化
class 类名{ static{ 数据初始化值; } }
构造代码块
用法:把多个构造方法的重复的部分写在里面,减少码量
class 类名{ { 重复的代码 } 构造方法; }
在创建对象时,会优先执行构造代码块里的代码,每次调用构造方法,都会执行
- 写在成员位置的代码块
- 每次无论调用什么构造方法都会执行
- 执行时,优先于构造方法
注: 现通常用调用构造方法的方式,只写一个构造方法内,用另一个构造方法去调用此构造方法传递默认值,或写成普通方法调用
十九, 抽象类和抽象方法 (用abstract修饰)
抽象方法 给多个子类共有的的方法创建规则
将子类共同的行为抽取到父类之后,不写方法体
public abstract void 方法名();
抽象类
abstract class 类名{ 抽象方方法或普通方法; }
- 抽象类不能实例化对象
- 抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
- 其子类必须重写所有的抽象方法,或者声明自己本身为抽象类
- 可以有构造方法
二十, 接口
作用:作为类共有方法定义创建的规范
定义: 关键字 interface
public interface 接口名{ }
接口不能实例化,需要通过类来实现 关键词 implements
一个类何以实现多个接口
class 类名 implements 接口1,接口2{ }
- 可以在继承的同时实现接口
public class 子类名 extends 父类名 implements 接口1,接口2{}
- 接口内的方法都是抽象方法
- 接口的实现类要么是抽象类,要么重写所有的抽象方法
- default修饰的方法可以有方法体
二十一, 内部类
类的五大成员之一
类的五大成员: 属性,方法,构造方法,代码块,内部类
定义:
class 类名{ class 类名{ } }
特点: 内部类可以直接访问外部类的成员,包括
- 内部类 可以直接访问外部类的成员,包括私有
- 外部类要访问内部类成员,必须创建对象
成员内部类 [了解]
格式:
class Oueter{ // 外部类 String name; class Inner{ // 成员内部类 int age; } }
特点:
- 成员内部类写在成员位置
- 成员内部类可以被一些修饰符修饰,比如:private,protected 和 pubilc
- 定义不定义静态变量(JDK16之前)
创建方式:
1.在外部类中编写方法,对外提供内部类对象 class Oueter{ // 外部类 String name; private class Inner{ // 成员内部类 int age; } public Inner getInner{ return new Inner; } } 2.直接创建 外部类名.内部类名 对象名 = new 外部类对象. new 内部类对象; Oueter.Inner inner = new Outer().new Inner();
静态内部类
特点:
- 静态内部类也是成员内部类的一种
- 静态内部类只能访问外部类的静态变量和静态方法,如果想要访问非静态的需要创建外部类对象
格式:
class Oueter{ // 外部类 String name; private static class Inner{ // 成员内部类 int age; static void eat(){ System.out.println("吃"); } pubilc void drink(){ System.out.println("喝"); } } } 外部类名.内部类名 对象名 = new 外部类名.内部类名(); Oueter.Inner inner = new Oueter.Inner();
调用:
非静态方法: Oueter.Inner inner = new Oueter.Inner(); inner.drink(); 静态方法: Oueter.Inner.eat();
局部内部类
特点:
- 将内部类定义在方法里面,类似于方法里面的局部变量
- 外界时无法直接使用,需要在方法内部创建对象并使用
- 该类可以直接访问外部类成员,也可以访问方法内局部变量
格式:
class Oueter{ public void show{ int i = 10; //局部内部类 class Inner{ 变量; 方法; } } }
匿名内部类[🔺🔺🔺重要]
定义:隐藏了名字的内部类
格式:
new 类名或接口名(){ 重写方法; }
特点:
- 在类中重写类或接口的方法
运用:
pubilc static 方法名(类名或接口名 变量名){ 变量名.重写的方法(); } 调用时: 方法名( new 类名或接口名(){ 重写方法; } );
例子:
abstract class Animal{ public void eat(); } public class Test{ public static void main(String[] args){ method( new Animal(){ @Override public void eat(){ System.out.println("狗吃骨头"); } } ); } public static void method(Animal a){ a.eat(); } }
二十一, 拼图小游戏 [🔺🔺🔺综合]
GUI : 图形化界面
运行组件:JFrame(外层窗体) , JMenuBar(上层菜单) , JLable(管理文字和图片)
总结:
object类
toString
equals
hashCode
set集合
HashSet
TreeSet
ArrayList
LinkedList
匿名内部类