Part 1:面向对象
面向对象
定义
面向对象是一种编程思想,比之之前的面向过程编程更加高效;在我们编程过程中,我们程序员习惯把实类中的一切抽象成为对象;自上而下进行代码执行。
面向对象过程的地址分析
简单总结:主方法自上而下代码顺序执行,主方法先进行压栈执行,然后执行对象的实例化,在堆中创建地址(地址一般为16进制数);然后调用对象中的方法,方法压栈执行,执行完毕之后弹栈跳出;对象方法结束之后,返回主方法,主方法结束之后弹栈,然后栈中的地址变成无引用数据,被垃圾回收机制处理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMpuaPMS-1678621378505)(2.20-2.26周总结.assets/面向对象的栈堆内存分析.png)]
类与对象的关系
类是对象的模板,对象是类的实例;
方法
方法的定义
解决问题的方法,包含实行功能的的代码段
方法的格式
public void(无返回值)||数据类型 (有返回值)方法名(){
代码段
}
ps:与返回值的方法要加return
//void,无返回值类型
public static void getSum(double i, int j) {
double result = i + j;
System.out.println(i + "+" + j + "的和为" + result);
}
//有返回值
public double getPrice() {
return price;
}
对象的创建
对象是new出来的。对象是类的具体实例;对象具有一定的状态和功能;
对象创建的核心是对对象的实例化
Student student = new Student();
成员的调用
成员属性的调用
成员属性可以通过类名|方法名进行调用;但是注意被不同修饰符修饰的方属性有不同的作用域;
成员方法的调用
1:在修饰符作用域允许的情况下,可以通过类名.方法名进行调用
2:通过对象的实例化对象时来进行调用
3:当方法被定义在类中方法外中,且被Static修饰,则在主方法中,可以通过方法名直接进行调用
构造器
什么是构造器
构造器,是没有返回值,且与类名同名的特殊的方法;
构造器的作用
为类中的定义的属性赋初始值;空参构造的情况下,我们会对类中属性其赋空值;整形赋为0;浮点型赋为0.0;String类型赋为null,boolean赋为false;
构造器的使用
构造器的重载
构造器是特殊的方法,可以构成重载,注意参数列表不同
构造器的语法格式
public 类名(参数列表){
}
//测试构造器
//学生类进行测试
public class Class001_ForStudent {
public String studentName;
public int studentAge;
public String studentSex;
//开始进行进行空参构造
public Class001_ForStudent(){
System.out.println("测试空参构造");
}
//为构造器进行赋一个值
public Class001_ForStudent(String name){
studentName=name;
System.out.println("有参构造,传入一个学生姓名");
}
//为构造器赋两个值
public Class001_ForStudent(String name , int age){
studentName=name;
studentAge=age;
System.out.println("有参构造,传入两个参数");
}
//定义的一个方法
public void message(){
System.out.println("学生的姓名是"+studentName+"!学生的性别是"+studentSex+"!学生的年龄"+studentAge);
}
}
this关键字
定义
指代当前对象
使用
在构造器中:
1:this(参数列表)可以调用其他构造器;注意在调用其他构造器时this一定要放在首行,而且不要再两个构造器之间相互使用this进行调用,当心造成构造器逻辑层面上死循环;
在类中
用以区分重名问题:this.属性,指代类中的属性,而不用this指向的则根据就近原则进行指代
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BJjb2NeE-1678621378506)(2.20-2.26周总结.assets/this关键字.png)]
statci关键字
静态方法
static修饰的方法为静态方法,静态方法可以在主方法中直接通过方法名调用;
静态变量
被static修饰的变量为静态的变量,静态变量跟随类的第一次执行而创建,静态数据独立存在,不存在栈中,不与成员变量相同,成员变量随着类的初始化而初始化,而static修饰的常量不会
静态块
静态块,格式为static{ 代码块 } ,位置在类中方法外,跟随类而创建,第一个执行;静态块一般被用于配置环境,如JDBC的导入
block块
静态块
静态块,格式为static{ 代码块 } ,定义位置为类中方法外,跟随类而创建,第一个执行;静态块一般被用于配置环境,如JDBC的导入
static {
a = 6;
System.out.println("1 、静态代码块执行a=" + a); //
}
构造块
构造块的定义位置为类中方法外,定义格式为{ 代码块},构造块一般的作用为为类中的属性进行赋值,但是构造块会在this调用构造器之后进行执行。构造块的执行时间是跟随new的执行而执行
同步块(以后学了在进行补充)
局部代码块
局部位置,一般定义在方法中;跟随方法的执行而执行;主要作用是语义化和区域化
public class Class002_BlockTest {
public static int a = 0;
{//构造块
a = 10;
System.out.println(" 3 、非静态代码块执行a=" + a); //
}
static {//静态块
a = 6;
System.out.println("1 、静态代码块执行a=" + a); //
}
public Class002_BlockTest() {
this(a); //
System.out.println(" 5、"+a); //
System.out.println(" 5、无参构造方法执行a=" + a); //
}
public Class002_BlockTest(int n) {//传入之后立刻执行构造快,因为构造快比构造器先执行
System.out.println(" 4、"+n); //6
System.out.println("4 、"+a);//
}
public static void main(String[] args) {
System.out.println("2 、main"); //
Class002_BlockTest tsc = new Class002_BlockTest();
}
}
封装(面向对象三个特性之一)
作用
隐藏内部的实现细节,对外提供公共的访问方式
封装属性的对外访问
getter和setter方法,设置对外的访问和修改方式
class Class01_Private1 {
private int age ;
private String name;//封装
public Class01_Private1() {
//空参构造
}
//设置方法可以更改age值
public void setAge(int age){
this.age=age;
}
//设置name初始值
public void setName(String name) {
this.name = name;
}
//访问设置
public int getAge() {
return age;
}
//访问设置
public String getName() {
return name;
}
//展示方法
public void show(){
System.out.println(name+" --->"+age);
}
}
import包导入
导包一般放在文件首行进行导入;
导包方式
1;模糊导入例:import java.util*;
2:statci指定类型导入:
import static java.lang.Math.PI;
3:使用位置定位来进行导入;但是这样的导入方式只能用一次
java.util.Scanner sc2= new java.util.Scanner(System.in); //java.util就是Scanner所在的包下
JavaBean的定义规范
1.类是公共的
2.至少提供一个空构造
3.属性私有化
4.提供一对公共的访问方式
继承(面向对象三大特性之一)
定义
子承父业,子类一旦继承父类就有权使用父类中的成员
关键字和实现方法
extends ;继承
class cat extends Animal1{
继承的优缺点
优点:提高了代码段复用性
缺点:代码与代码之间耦合性太高
重载Overload
定义:同一个方法名,不同的参数类型,为了实现相同的功能的,但是实现的方法不同
实现条件:同一个类中,方法名相同,参数列表不同;
ps:是否构成重载只与方法的标签有关,与其他的无关
public static void getSum(int x,int y){
System.out.println("2个int整数和="+(x+y));
}
public static void getSum(int x,int y,int z){
System.out.println("3个int整数和="+(x+y+z));
}
重写Override
重写的作用
重新定义方法的动能,将父类的方法进行改写;
重写的实现条件
1.两个类中的两个方法
2.继承|实现关系
3.方法签名完全相同
重载和重写的区别
1:发生场景不同:重载发生在同一个类中;而重写发生在两个类中;
2:目的不同;重载是因为参数列表不同,但是两个方法的所达到的功能还是相同的;但重写发生在两个类中,重写的方法标签相同,功能不同,重写的存在是因为子类对父类的功能不满意,因此对父类的功能进行重新书写的方法;
3:相同点:都是方法的重要特性
super关键字
作用和使用:
作用:1;调用父类成员(父类变量||父类方法1)
2:区别子父类的重名问题
使用:在指向父类构造器时,放在子类构造器的首行;
public class Class01_SuperTest {
public static void main(String[] args) {
Student student = new Student();
student.sleep(10010);
}
}
class Person{
int age ;
String name ;
public void sleep(String name,int age){
System.out.println(name+"--->"+age+"正在睡觉");
}
}
class Student extends Person{
int studentID;
public void sleep(int studentID){
super.sleep("李四",19);
System.out.println("睡觉的人的学生ID为"+studentID);
}
}
final最终的(关键字)
1:被final修饰的变量为常量,常量的驼峰命名原则为,所有单词全部大写,单词与单词之间用下划线_进行连接;
2:final修饰的方法不能被重写
3:final修饰的类不能被继承
多态(面向对象三大特性之一)
定义
一种事物的多种形态,一个功能的不同实现方式
多态的实现条件
1:继承或实现关系
2:父类引用指向子类 || 接口引用指向实现类
3:重写
Cast转型
定义:
对应类型的数据赋值给对应类型的变量
向上转型-------->多态
向下转型
向下转换的意义就是因为父类对子类的调用是屏蔽子类新功能的添加的;因此父类不能调用子类新增的功能,但是通过强转就可以达到直接调用
//Cast测试
public class Class01_CastTest {
public static void main(String[] args) {
//多态转化
Person person = new Student();
Student student =(Student) person;//强转给了子类,通过子类进行调用
student.test();
}
}
class Person{
public void show(){
}
}
class Student extends Person{
@Override
public void show(){
System.out.println("student子类");
}
public void test(){
System.out.println("测试转型");
}
}
class Teacher extends Person{
@Override
public void show(){
System.out.println("teacher子类");
}
public void run(){
System.out.println("run成功");
}
}
抽象类:Abstract class
定义:使用可以使用属性,构造器具体方法,抽象方法……
使用:需要通过子类具体对象来进行使用
特点:单继承机制,extends,作为父类,不能实例化
//测试abstract抽象
public class Class01_Abstract {
public static void main(String[] args) {
Abstract2 abstract2 = new Abstract2();
abstract2.run();
abstract2.show();
Abstract4 abstract4 = new Abstract4();
abstract4.run();
abstract4.show();
}
}
abstract class Abstract1{
//抽象类中,默认所有的方法和属性均为抽象的
public abstract void show();
public abstract void run();
}
class Abstract2 extends Abstract1{
@Override
public void show() {
System.out.println("我很帅");
}
@Override
public void run() {
System.out.println("三千米,不在话下");
}
}
//没有完全将父类进行重写,所以依旧为abstract类,要想将其实现,要进行实例化
abstract class Abstract3 extends Abstract1{
public void show(){
System.out.println("你也很帅");
}
}
class Abstract4 extends Abstract3{
@Override
public void run() {
System.out.println("三千米,累死人");
}
}
接口Interface
接口的特点
1:Interface接口内方法基本都是方法;接口内的定义的方法默认被abstract 修饰,因为要想实现implements接口,就必须通过具体化子类对象
2:接口能够实现多继承,而类只能实现单继承;
3:接口的实现,必须要依靠重写;
4:在类同时要实现继承和接口时,要先进行类的继承,然后才能进行接口的实现
5:类与类之间:单继承
6:类与接口之间:多继承
7:接口与接口之间:多继承
//interface测试
public class Class01_Interface {
public static void main(String[] args) {
True1 true1 =new True1();
true1.show2();
true1.test();
true1.show();
true1.test1();
}
}
interface method{
abstract void test();
abstract void show();
}
interface method2{
abstract void test1();
abstract void show2();
}
//抽象子类接口
abstract class True implements method,method2{//类的多实现
@Override
public void show() {
System.out.println("show");
}
@Override
public void test() {
System.out.println("test2");
}
}
class True1 extends True implements method,method2{//先继承在进行实现
@Override
public void test1() {
System.out.println("test1");
}
@Override
public void show2() {
System.out.println("show2");
}
}
接口的新增特性
JDK1.7之前
1;接口内定义的变量默认被public static final修饰
2: 接口内定义的方法默认被public abstract 修饰
JDK1.8新增
静态方法||默认方法
JDK新增的为私有方法
在Interface中被private修饰的方法,只能在interface中调用,其他地方不行
//测试java1.8及其之后的接口新特性
public class Class02_InterfaceTest {
public static void main(String[] args) {
A a = new B();
a.methodTest();
a.show();
B b = (B)a;//接口强转,调用实现类新增的方法
b.test1();
}
}
interface A{
public void methodTest();//普通方法
//静态方法
public static void run(){
System.out.println("静态方法");
}
default void show(){
run();//默认方法中可以调用静态方法
test();//可以调用接口中私有的方法
System.out.println("默认方法");
}
private void test(){//私有方法
System.out.println("私有方法");
}
}
class B implements A{
@Override
public void methodTest() {
System.out.println("测试接口多台");
}
//新增方法
public void test1(){
System.out.println("子类新增方法");
}
}
Part 2:数组
数组的特点
1:数组有固定的长度
2:数组要求存储的数据全部都是一种类型
3:数组的排列是有序的,根据索引的下标进行对数组进行排序;注意:数组的索引从0开始
4:数组在没有进行赋值时,存在默认值;整数 : 0,小数 : 0.0; 布尔 : false;字符 : 空字符" ";String类型为Null
一维数组
数组的声明:
(数据类型)【】数组名 = new 数据类型【】{ 数组值 };(静态初始化)
(数据类型)【】数组名= new 数据类型【数组长度】;(动态初始化)
一维数组的遍历
1:for循环
2:foreach循环 || 增强for循环
二维数组
数组的声明
静态声明:数据类型【】【】数组名= { {值列表1},{值列表2}……}
动态声明:数据类型[][]数组名= new 数据类型【外层数组的长度】【内层一维数组的长度】
二维数组的遍历方式
就是一位数组的两个循环的嵌套使用
public class Class01_ArrayTest {
public static void main(String[] args) {
int [][]num = new int[2][3];
int [][]num1= {{1,2,3},{3,2,1,},{4,5}};
int num3[]= new int[]{1,2,3};
num[0][0]=1;
num[0][1]=2;
num[0][2]=3;
num[1][0]=4;
num[1][1]=5;
num[1][2]=6;
for(int a:num3){
System.out.print(a+" ");
}
System.out.println();
fill(num3,1);
for(int a:num3){
System.out.print(a+" ");
}
System.out.println();
//foreach嵌套
for (int[] a: num) {
for (int b: a) {
System.out.print(b+" ");
}
}
System.out.println();
//for循环嵌套
for(int i =0;i< num1.length;i++){
for (int j = 0; j < num1[i].length; j++) {
System.out.print (num1[i][j]+" ");
}
}
System.out.println();
//for+foreach循环嵌套
for (int i = 0; i < num.length; i++) {
for(int a :num[i]){
System.out.print(a+" ");
}
}
System.out.println();
//foreach+for
for( int[] a:num1){
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
}
}
数组工具包Arrays
以下仅为一部分;遇见不懂的就查询API;
//Arrays工具包局部内容侧视
public class Class02_ArraysTest {
public static void main(String[] args) {
int []num1 = new int[5];
int [] num2 = {2,5,1,5,9,10};
int [] num3 = {2,5,8,5,7,10};
//测试fill,数组的填充
fill(num1,100);
System.out.println(Arrays.toString(num1));
//测试数组指定下标进行填充,从下标1-3 fill
fill(num1,1,3,10);
System.out.println(Arrays.toString(num1));
//sort,对数组进行排序,进行升序排序 Arrays.sort()
Arrays.sort(num2);
System.out.println(Arrays.toString(num2));
//对数组进行指定范围进行排序
Arrays.sort(num3,1,5);
System.out.println(Arrays.toString(num3));
//创建数组,进行数组与数组之间的拷贝 Arrays.copyOf
System.out.println(Arrays.toString(Arrays.copyOf(num3,3)));
System.out.println(Arrays.toString(Arrays.copyOf(num2,3)));
System.out.println(Arrays.toString(Arrays.copyOf(num1,3)));
//指定数组的长度,copy到指定数组
System.out.println(Arrays.toString(Arrays.copyOfRange(num1,2,3)));
//指定源数组中的数组从指定位置开始复制到目标数组的指定位置。
System.arraycopy(num2,1,num3,2,3);
//将数组num1,从下标1开始copy到数组num2,num2从下标2开始接受,长度为3
System.out.println(Arrays.toString(num3));
}
}
2);
System.out.println(Arrays.toString(num2));
//对数组进行指定范围进行排序
Arrays.sort(num3,1,5);
System.out.println(Arrays.toString(num3));
//创建数组,进行数组与数组之间的拷贝 Arrays.copyOf
System.out.println(Arrays.toString(Arrays.copyOf(num3,3)));
System.out.println(Arrays.toString(Arrays.copyOf(num2,3)));
System.out.println(Arrays.toString(Arrays.copyOf(num1,3)));
//指定数组的长度,copy到指定数组
System.out.println(Arrays.toString(Arrays.copyOfRange(num1,2,3)));
//指定源数组中的数组从指定位置开始复制到目标数组的指定位置。
System.arraycopy(num2,1,num3,2,3);
//将数组num1,从下标1开始copy到数组num2,num2从下标2开始接受,长度为3
System.out.println(Arrays.toString(num3));
}
}