java周总结(二)

本文详细介绍了Java中的循环结构,包括for和while的区别,以及死循环的应用。接着讲解了方法的定义、分类和重载。深入探讨了数组的定义、初始化、遍历以及内存分配,特别提到了栈和堆的区别。文章还涵盖了多维数组的定义和初始化。最后,重点阐述了面向对象的特性,如封装、继承和多态,解析了成员变量和局部变量的差异,并对比了抽象类与接口以及final关键字的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.for循环与while循环的区别

1.格式

for循环:			
			for(初始化语句;条件表达式;步长语句){
					循环体语句;
			}
while循环:			
			初始化语句;
			while(条件表达式){
				循环体语句;
				步长语句;
			}	

2.是否节省内存空间

 for循环结束,这个变量及时从内存中释放掉了
 while循环结束,这个变量依然可以访问的

3是否明确循环次数

 for循环:明确循环次数
 while循环:不明确循环次数

二.死循环及其应用

格式:

格式1:
			for(;;){
				
				循环体语句;
			}
			
格式2:(推荐)
			while(true){
				
				循环体语句;
			}

应用:

需求:使用Math类中的方法 random()获取一个1-100之间的随机数

//导包
import java.util.Scanner;
class GuessGame{
	public static void main(String[] args){
	    //产生一到一百之间的随机数
		int number = (int)(Math.random()*100+1);
		//做while死循环
		while(true){
			Scanner sc = new Scanner(System.in);
			System.out.println("请输入你要猜的数字:");
			int guess = sc.nextInt();
			//做if判断,提示大小,猜对直接结束
			if(guess>number){
				System.out.println("你猜大了");
			}else if(guess==number){
				System.out.println("你猜对了");
				break;
			}else{
				System.out.println("你猜小了");
			}
		}
	}
}

三.方法

1.概念

 使用{}将代码包裹起来,并给这个代码起一个名字:方法名---->以后直使用方法名调用.

2.分类

<1>有返回值类型的方法的定义

1.固定格式:
public static 返回值类型 方法名(形式参数类型1 参数名称1,...){
				
				业务需求...
				return 结果;
}
2.调用方法:赋值调用
  需求:求和两个数据的和
  两个明确:
	1)明确返回值类型: int类型
	2)明确参数类型以及参数个个数:int类型   两个参数求和
	public static void main(String[] args){
		//调用add()方法,输出结果
		add(10,20);
		System.out.println("二者之和为:"+add(10,20));	
    }
    public static int add(int m,int n){
    
		//返回需求结果
		return m+n ;		
	}
	
  /*注意事项:定义方法时,必须携带参数类型;
          调用方法时,实参不用携带数据类型.*/

<2>无返回值类型的方法定义

语法要求:如果没有具体返回值结果,使用void来代替返回值类型

//1.定义格式:
	public static void 方法名(形式参数类型1 变量名1,..){
		直接输出语句或者
		其他业务操作;
	}
/*2.实例:
  需求:键盘录入一个n数据,打印nn乘法表*/
import java.util.Scanner;
class Demo{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入乘法表阶数:");
		int n = sc.nextInt();
		printChengfabiao(n);
    }
	public static void printChengfabiao(int n) {
		for(int x = 1 ; x <= n ;x ++){
			for(int y = 1 ; y <= x ; y ++){
				System.out.print(y+"*"+x+"="+y*x+"\t") ;
			}
				System.out.println() ;
		}	
	}
}
				
注意:Java中不存在void类型(替代词)

3.重载

定义: 方法名相同,参数列表不同,与返回值无关.

参数列表不同:

  1)数据类型一样的,参数个数不同

  2)参数个数一样,类型不同

  参数个数不一样,参数类型不同

//举例:求n个数之和,方法名均为sum;
class FunctionDemo{
	public static void main(String[] args){
		//使用实际参数
		//输出调用
		System.out.println(sum(10,20)) ;
		System.out.println("------------------") ;
		//System.out.println(sum2(10,20,30)) ;
		System.out.println(sum(10,20,30)) ;
		
		System.out.println("------------------") ;
		//System.out.println(sum3(10,20,30,40)) ;
		System.out.println(sum(10,20,30,40)) ;
		System.out.println(sum(1.34,2.35)) ;
	}
	
	//定义两个数据之和的方法
	public static int sum(int a ,int b){
		return a + b ;
	}
	
	
	
	//一模一样的方法:方法名相同,参数类型都一样:重复定义!
	/*
	public static int sum(int a ,int b){
		return a + b ;
	}
	*/
	
	public static double sum(double a,double b){
		return a + b ;
	}
	
	//定义三个数据求和的方法
	//public static int sum2(int a,int b,int c){
	public static int sum(int a,int b,int c){
		return a + b + c ;
	}
	
	//定义四个数据求和的方法
	//public static int sum3(int a,int b,int c ,int d){
	public static int sum(int a,int b,int c ,int d){	
		return a + b +c + d ;
	}
}

四.数组

1.定义:

  • 数组是存储同一数据类型多个元素的集合,也可以看成是一个容器
  • 数据既可以存储基本数据类型,也可以存储引用数据类型

2.格式

  • 数据类型[] 数组名称;
  • 数据类型 数组名称[] ;

3.初始化化:

动态: 指定数组长度,系统默认给元素分配值

  • 数据类型[] 数组名称 = new 数据类型[数组长度] ;
  • 数据类型 数组名称[] = new 数据类型[数组长度] ;

静态:直接指定了元素值,系统默认分配长度

  • 数据类型[] 数组名称= new 数据类型[]{元素1,元素2,…} ;
  • 数据类型 数组名称= new 数据类型[]{元素1,元素2,…} ;

静态初始化的简化格式:

  • 数据类型[] 数组名称 = {元素1,元素2,元素3…} ;
  • 数据类型 数组名称[] = {元素1,元素2,元素3…} ;

4.数组的遍历(规范格式)

class Array1{
	public static void main(String[] args){
		int[] arr = {1,2,3,4,5,6,7};
		printArray(arr);
	}
	public static void printArray(int[] arr){
		System.out.print("[");
		//x表示角标,从0开始
		for(int x=0;x<arr.length;x++){
			//判断当角标达到最大时,输出元素同时,加上右中括号
			if(x==arr.length-1){
				System.out.println(arr[x]+"]");
			}else{
				System.out.print(arr[x]+" ,");
			}
		}	
	}
} 

冒泡排序的实现

冒泡排序的思想:
    两两比较,大的往后放,第一次比较完毕,最大值就出现在最大索引处!
规律:
	两两比较,大的往后放
	第一次比较:0个不比
	第二次比较:1个不比
	...
	...
    最终比较的次数:就是当前数组长度-1
核心代码:
		for(int x = 0 ; x < arr.length-1 ; x ++){//比较的次数
			//内层循环:元素之间:两两比较,大的往后放
			for(int y = 0 ; y < arr.length-1-x ; y ++){
				//判断
				if(arr[y] > arr[y+1]){
					//中间变量
					int temp = arr[y] ;
					arr[y] = arr[y+1] ;
					arr[y+1] = temp ;
				}
			}
		}

5.内存分配

  Java 程序在运行时,需要在内存中的分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

(1) 栈: 存储局部变量,被调用方法参数

  • 优点:存储速度比堆快,仅次于寄存器,栈数据可以共享。
  • 缺点:数据的大小和生存期必需确定,缺乏灵活性。

(2) 堆:存放由new创建的对象和数组

  • 优点:可动态分配存储空间大小,Java垃圾回收器会自动收走不使用的数据
  • 缺点:由于动态分配内存,存取速度较慢

(3) 方法区方法区中存放了每个Class的结构信息

(4) 本地方法区(和系统有关)

(5) 寄存器(供CPU使用)

五.多维数组

1.定义:就是元素为一维数组的一个数组。

2.初始化格式

格式1:

  • 数据类型[][] 数组名 = new 数据类型[m][n];
  • m:表示这个二维数组有多少个一维数组。
  • n:表示每一个一维数组的元素有多少个。

格式2:

  • 数据类型[][] 数组名 = new 数据类型[m][];
  • m:表示这个二维数组有多少个一维数组。
  • 列数没有给出,可以动态的给。这一次是一个变化的列数。

格式3:

基本格式:

  • 数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2…},{元素1,元素2…},{元素1,元素2…}};

简化版格式:

  • 数据类型[][] 数组名 = {{元素1,元素2…},{元素1,元素2…},{元素1,元素2…}};

说明:int[] arr = new int[3];

  • 左边:
    int:说明数组中的元素的数据类型是int类型
    []:说明这是一个数组
    arr:是数组的名称
  • 右边:
    new:为数组分配内存空间。
    int:说明数组中的元素的数据类型是int类型
    []:说明这是一个数组
  • 数组长度: 其实也就是数组中元素的个数

3.遍历二维数组(规范格式)

//举例:二维数组:{{1,2,3},{4,5,6},{7,8,9}}
class lianxi42{
	public static void main(String[] args){
		int[][] arr={{1,2,3},{4,5,6},{7,8,9}};
		printArray2(arr);
	}
	public static void printArray2(int[][] arr){
		System.out.print("{");
		//x表示数组的个数
		for(int x=0;x<arr.length;x++){
			System.out.print("{");
			//y表示数组的长度
			for(int y = 0;y < arr[x].length ; y++){
			//每个数组中索引值最大的元素,且不是索引值最大的数组
				if(y==arr[x].length-1 && x!=arr.length-1){
					System.out.print(arr[x][y]+"}"+",");
				}else if(y==arr[x].length-1 && x==arr.length-1){
					System.out.println(arr[x][y]+"}}");
				}else{
					System.out.print(arr[x][y]+",");
				}
			}
		}
	}
}

六.面向对象

1.特点

  • 更符合生活中的思想行为习惯
  • 让我们从执行者变成了指挥者
  • 把复杂的事情简单化
//测试类(有main()方法的即为测试类)
class StudentList{
	public static void main(String[] args){
		//创建对象操作
		Student student = new Student("张三",20,"男","高三十八班");
		//输出学生基本信息
		System.out.println(student.name+"----"+student.age+"---"
		+student.sex+"---"+student.sclass);
		//[3]调用成员方法
		student.sleep();
		student.playgame("王者峡谷");
		student.study();
	}
}
class Student{
	String name;
	int age;
	String sex;
	String sclass;
	public void study(){
		System.out.println("他在学习");
	}
	public void sleep(){
		System.out.println("她在睡觉");
	}
	public void playgame(String name){
		System.out.println("他在"+name+"战斗");
	}
	//有参构造
	public Student(String n,int a,String s,String sc){
		name = n;
		age = a;
		sex = s;
		sclass = sc;
	}:[1]类名 对象名 = new 类名();
    对象名可以自定义,括号为空,为无参构造,需要通过 对象名.变量名 = ---;按照形参类型合理赋值;
    [2]先写基本类,再写测试类;基本类中 成员变量,无参构造,有参构造,成员方法

2.特征

  • 封装
  • 继承
  • 多态
    2.1 封装
    将本类的属性(成员变量 )私有化(为了保证数据安全性),对外提供公共访问的方法;
//第一行包名自定义
public class Person {
   //利用关键字private对成员变量进行初始化
   private String name;
   private int age;
   private String gender;
   //提供无参构造方法(Alt+shift+s---->c)
   public Person() {
   	super();
   }
   //提供有参构造方法(Alt+shift+s---->o)
   public Person(String name, int age, String gender) {
   	super();
   	this.name = name;
   	this.age = age;
   	this.gender = gender;
   }
   //提供公共访问方法(Alt+shift+s---->r)
   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;
   }
   
   public String getGender() {
   	return gender;
   }

   public void setGender(String gender) {
   	this.gender = gender;
   }	
}:super():父类的地址值引用(继承标志性关键字),这里是继承Objct类的无参构造,可以不写
   setXxx(形参列表):遵循小驼峰命名法,用来赋值操作,在测试类中通过**对象名.setXxx(实参)**赋值;
   getXxx():取值操作,在测试类中通过System.out.println(对象名.getXxx()),取值并输出;
   快捷键:括号里面的为eclipse里面的快捷键,例如:Alt+shift+s---->r,就是同时按住Alt,shift,s键然后松开,再按个r键
   注意:在测试类中,先赋值,再取值(先set再get)

2.2 继承

  目的: 为了解决代码冗余问题,提高代码复用性,继承来了,将共有的属性或者方法通过继承共用

  定义: 将多个类的共同具有的内容放到一个单独的类中,这些类与这个单独类具有继承关系

class Grandfather{
	public void funtion(){
		System.out.println("我是爷爷");
	
	}
}

class Father extends Grandfather{
	public void method(){
		System.out.println("我是爸爸");
	}
	
}

class Son extends Father{
	String name;
	//无参构造
	public Son(){}
	//有参构造
	public Son(String name){
		this.name = name;
	}
	public void ff() {
		System.out.println("本尊");
	}
}

public class ExtendTest {
	public static void main(String[] args) {
		Son son = new Son();
		son.method();
		son.ff();
		son.funtion();
	}
}:
[1]class 类名 extends 父类名 {}   
	这是一个子类,继承父类,子类具有父类的属性和方法;
[2]构造方法:为了数据初始化而诞生;
	书写:权限修饰符(例如public) 方法名与类名完全一致 {------------}
	分类:无参构造,有参构造;
	顾名思义,有形参即为有参构造,无形参则无参构造,
	有参构造的形参类型与成员变量的数据类型保持一致;
[3]如果形参变量名与成员变量名一样(即就是局部变量与成员变量),这时候,this关键字诞生了;
	this:本类对象的地址值引用,this.变量名 就表示当前类的成员变量;

成员变量与局部变量的区别;
1.书写位置

  • 成员变量:位于类的内部,方法外
  • 局部变量:位于方法的声明和定义出

2.内存位置

  • 成员变量:在堆内存
  • 局部变量:在栈内存

3.生命周期

  • 成员变量:随着对象的创建完毕而存在,随着对象被Gc回收而消失
  • 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

4.初始化

  • 成员变量:可以不用初始化,系统默认初始化
  • 局部变量:必须初始化,否则会报错,可以先定义后初始化,也可以直接初始化
super关键字与this关键字的区别
1.定义
super:父类对象地址值的引用
this:本类中的地址值引用

2访问成员
super.变量名表示父类的成员变量
this.变量名表示当前类的成员变量

super()表示引用父类的无参构造方法,有形参即为有参构造
this()指向本类的无参构造方法,同上

super.方法名:表示父类的对应方法
super.方法名:表示当前类的对应方法
--------------------------------------------------

2.3多态

定义: 一个事物在不同时刻呈现出不同的状态;

前提条件:在继承的前提下,重写父类方法,父类引用指向子类对象;

public class AnimanTest {
	public static void main(String[] args) {	
		//向上转型
		Animal a1 = new Cat();
		//调用static修饰的方法
		AnimalTool.method(a1);
		System.out.println("-----------------------");
		a1 = new Dog();
		AnimalTool.method(a1);
		System.out.println("-----------------------");
		Cat c1 = new Cat();
		c1.drink();
		System.out.println("-----------------------");
	}
	
}
class AnimalTool{
	private AnimalTool() {}
	public static void method(Animal a) {
		a.eat();
		a.sleep();
	}
}
class Animal{
	//方法重写
	public void sleep() {
		System.out.println("吃");
	}
	public void eat() {
		System.out.println("睡");
	}
}
class Cat extends Animal{
	public void sleep() {
		System.out.println("吃鱼");
	}
	public void eat() {
		System.out.println("站着睡");
	}
	public void drink() {
		System.out.println("喝水");
	}
}
class Dog extends Animal{
	public void sleep() {
		System.out.println("吃肉");
	}
	public void eat() {
		System.out.println("躺着睡");
	}
}:[1]向上转型,父类引用指向子类对象的体现
	父类名 父对象 = new 子类名 子类对象
   [2]方法重写:子类继承父类的过程中,子类出现了和父类一模一样的方法;
   即就是父类和子类的方法完全一致,	访问同一方法时,父类的方法就会被子类方法覆盖
   [3]方法重载:方法名相同,形参列表(形参个数,形参类型)不同,与返回值无关
   [4]static关键字见下

多态的成员访问特点:

  • 成员变量:编译看左,运行看左
  • 成员方法:编译看左,运行看右(方法重写)
  • 静态方法:编译看左,运行看左
  • 构造方法:分层初始化

static关键字

  • 随着类的加载而加载
  • 优先于对象而存在
  • 可以被多个对象共享共用
  • 修饰成员变量,成员方法,一般方法时候可以通过类名直接调用

3.抽象类

  • 有抽象方法(被bastract修饰)的一定是抽象类
  • 抽象类不一定有抽象方法
  • 没有抽象的方法不一定不是抽象类

引入:一个类的方法的内容不够具体,或者方法中内容为空,可以把这个类定义为抽象类;

abstract class Fu{
	public abstract void method();
}

class Zi extends Fu{
	@Override
	public void method() {
		System.out.println("子方法");
	}
	
}

public class Test {
	
	public static void main(String[] args) {
		Fu f = new Zi();
		f.method();
	}
}:抽象类,抽象方法必须带abstract,定义为抽象方法后,如果继承自该抽象类,
   则会强制重写(@Override);

4.接口

 接口就是一个新加的功能,用类实现接口,多接口;

interface Jump{
	//成员变量默认被final修饰,是一个常量
	int i = 2;
	void jump();
}

class Cat implements Jump{
	//重写接口方法
	@Override
	public void jump() {
		System.out.println("猫会跳高");
	}
	
}
//测试类
public class Test2 {
	public static void main(String[] args) {
		//不能直接实例化,需要通过接口多态实现
		Jump j = new Cat();
		System.out.println(j.i);
		j.jump();
	}
}:implements:表示实现接口
   interface:接口的关键字
   一个类可以继承另一个类的同时,实现多个接口
   final:表示最终的,不可更改的

final关键字

  • 修饰变量时,变量成常量
  • 修饰类时,该类不能被继承
  • 修饰成员方法时,该方法不能被重写

抽象类与接口的区别
成员区别:
   抽象类:
       成员变量可以是常量也可以是变量
       成员方法可以是抽象方法,也可以是一般方法
       构造方法可以是有参构造也可以是无参构造
   接口:
       成员变量成了常量
       成员方法只能是抽象方法
       没有构造方法
关系区别:
   类与类之间: 支持单继承,不支持多继承,支持多层继承
   类与接口之间; 在继承一个类的同时可以实现多个接口
   接口与接口之间: 存在继承关系,支持单继承,也支持多继承
设计理念:
    抽象类------>继承关系-------->体现"is a"关系
    接口------>体现额外功能----->是一种"like a"

5.内部类

定义:在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

5.1成员内部类

//外部类
class Circle {
    double radius = 0;
     
    public Circle(double radius) {
        this.radius = radius;
    }
    //内部类:位于成员位置
    class Draw {   
        public void drawSahpe() {
            System.out.println("drawshape");
        }
    }
}
//测试类
public class Test3 {
	public static void main(String[] args) {
		Circle.Draw d = new Circle(2).new Draw();
		d.drawSahpe();
	}
}:[1]访问成员内部类的方法,通过 外部类名.内部类名 对象名 = 外部类对象.内部类对象();
   [2]内部类可以直接访问外部类方法,变量;
   [3]如果成员内部类方法是静态方法时,通过外部类名.内部类名 对象名 = new 外部类名.内部类名();
   [4]当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下
   访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
	      外部类.this.成员变量
	      外部类.this.成员方法	 
	              

5.2局部内部类

//外部类
class People{
    public People() {
         
    }
}
 
class Man{
    public Man(){
         
    }
    public People getWoman(){
    	//局部内部类:方法中,即局部位置
        class Woman extends People{  
            int age =0;
        }
        return new Woman();
    }
}:局部内部类就像是方法里面的一个局部变量一样,是不能有 publicprotectedprivate 
   以及 static 修饰符的。

5.3匿名内部类

abstract class Teacher{
	public abstract void method();
}
class TeacherDemo{
	public void show (Teacher t) {
		t.method();
	}
}

public class TeacherTest {
	public static void main(String[] args) {
		TeacherDemo t = new TeacherDemo();
		t.show(new Teacher() {

			@Override
			public void method() {
				System.out.println("好好学习,天天线上");
			}	
		});
	}
}:抽象类不能直接实例化,可以借助匿名内部类可以作为实参进行实例化;

interface Smoke{
	abstract void show();
}

class Outer2{
	public static Smoke method() {
		return new Smoke() {
				@Override
				public void show() {
					System.out.println("好好学习,,,");
				}			
		};
	}
}
public class StudentList {
	public static void main(String[] args) {
		Outer2.method().show();
	}
}:类名直接方法,static方法,可以访问show方法,method方法返回值类型为接口对应的Smoke;
   接口作为返回值类型,return一个匿名内部类对象

附:选择排序

public class SelectSort {
	public static void main(String[] args) {
		int[] arr = {10,9,12,6,8};
		paixu.xuanze(arr);
		paixu.printArray(arr);
	}
}
class paixu{
	public static void printArray(int[] arr) {
		System.out.print("[");
		for(int x = 0;x<arr.length;x++) {
			if(x==arr.length-1) {
				System.out.println(arr[x]+"]");
			}else {
				System.out.print(arr[x]+",");
			}
		}
	}
	public static void xuanze(int[] arr) {
		for(int x =0;x<arr.length-1;x++) {
			for(int y =x+1;y<arr.length;y++) {
				if(arr[y]<arr[x]) {
					int temp = arr[x];
					arr[x] = arr[y];
					arr[y] = temp;
				}
			}
		}
	}
}
分析:索引为0对应的数,和其他的比较(索引为1以及之后),小的往前放,第一次比较完毕,
    最小的就出现在了最小索引处;
	索引为1对应的数,和其他的比较(索引为2以及之后),小的往前放,第二次比较完毕,
    -----------------------
    -----------------------------------------------------------------
    发现:每次比较都是和其后一位先开始,然后一直到最后一个;
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值