JavaSE(java基础)

第一阶段

在这里插入图片描述

转义字符Value
\t制表位,实现对齐功能
\n换行
\r回车
\’一个 ’
\"一个 "

1、数组

数组是一种数据类型,引用类型。
数字型数据本质上是个对象object

double[] array = {1,2,3,4,5,5.6,3};
int[] array = new int[5]; //5是数组的大小
int[] array = new int[]{1,2,3,4,5,6};
for(int i = 0;i<array.length;i++)

//基本数据类型,赋值方式为值拷贝/值传递
int a= 13;
int b = a;

//数组在默认情况下是引用传递/地址拷贝,赋值是赋地址值,赋值方式为引用赋值
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
//arr2[0] = 5 意思是将arr2[0]的地址指向的数值从1改为5,因为arr1和arr2地址是一样的,所以arr1[0]的值也变为5.
//数组拷贝,两个数组地址独立
int[] arr1 = {1,2,3,4,5};
int[] arr2 = new int[arr1.length];
for(int i =0 ;i<arr1.length;i++){
	arr2[i] = arr1[i]
}
//此时修改arr2的元素,并不影响arr1.
//冒泡排序(从小到大)
int[] arr1 = {24,69,80,57,13};
int temp = 0;
for(int i = 0 ; i<arr.length-1;i++){
	for(int j = 0; j<arr.length-1-i ; j++){
		if(arr[j] > arr[j+1]){
			temp = arr[j];
			arr[j] = arr[j+1];
			arr[j+1] = temp;
		}
	}
}

2、二维数组

内存分配:
二维数组内存概况

//二维数组定义方式:
//方式一
int [][] arr = new int[2][3];
//方式二:列不确定
int[][] arr = new int[3][];//此时只分配了地址0x0011,一维地址内存需要自行重新给,比如:
for(int i=0; i<arr.length; i++){
	arr[i] = new int[i+1] //
}
//方式三,静态初始化
int [][] arr = {{1,1,1},{2,2,2},{3,3,3}}
//x是一维数组,y是二维数组
int[] x,y[];

方式二内存概况
方式二的内存概况

3、类与对象

class Cat(){
//猫的属性
	String name;
	int age;
	String color;
}
Cat cat = new Cat();//在方法去加载类的属性和行为
cat.name = "小白";//字符串,引用数据类型,在方法区常量池存储
cat.age = 12;  //基本数据类型直接在堆中
cat.color = "白色";

在这里插入图片描述
1、栈:一般存放基本数据类型
2、堆:存放对象(Cat cat,数组等)
3、方法区:常量池(常量,比如字符串),还加载类信息

在这里插入图片描述
int returnRes = p1.getSum(10,20)运行结束后独占栈空间消失,当程序运行完,main栈空间随之消失。

4、成员方法

4.1、注意事项

1、同一个类的方法直接调用:
2、跨类用对象名调用(也和修饰符有关,可以看后面内容)

class A(){
	public void print(){
		System.out.println("helloworld")
	}
	public void print_1(){
		print();//在同一类中直接方法名调用
	}
}
class B(){
	public viod main(String[] args){
		A a = new A();//创建对象
		a.print();//通过对象名调用
	}
}

4.2、成员方法的传参机制

4.2.1、基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参。
在这里插入图片描述
4.2.2、引用类型传递的是地址(传递的也是值,但是这个值是地址值),可以通过形参影响实参。(对象 也是传地址)
在这里插入图片描述
在这里插入图片描述
在class B中把p.age = 10000;改成p=null;最终输出p.age是10:
在这里插入图片描述
如果test200 执行的是 p = new Person();p.name = "Tom";p.age = 99;下面输出的还是10
在这里插入图片描述
克隆对象

public class test
 {
    public static void main(String[] args) {		
		B b = new B();
		Person p = new Person();
		p.name = "jack";
		p.age = 18;
		Person p2 = b.copy(p);
		p2.name = "tom";
		System.out.println("p的名字和年龄是"+p.name + " "+p.age  );//jack  18
		System.out.println("p2的名字和年龄是"+p2.name + " "+p2.age  );//tom  18
    }
}
class Person{
	String name;
	int age;
}
class B{
	public Person copy(Person p){
		Person p2 = new Person();
		p2.name = p.name;
		p2.age = p.age;
		return p2;
	}
} 

在这里插入图片描述

4.3、方法递归调用

public class test
 {
    public static void main(String[] args) {		
		T t1 = new T();
		t1.test(4);//程序运行结果应该为n=2  n=3  n=4
    }
}
class T{
	public void test(int n){
		if(n>2){
			test(n-1);
		}
		System.out.println("n="+n);
	}
} 

在这里插入图片描述

public class test
 {
    public static void main(String[] args) {		
		T t1 = new T();
		t1.factorial(5);//120
    }
}
class T{
	public void factorial(int n){
		if(n == 1){
			return 1;
		}else{
			return factorial(n-1)*n;
		}
} 

在这里插入图片描述

递归重要规则
1.执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2.方法的局部变置量是独立的,不会相互影响,比如n变量;
3.如果方法中使用的是引用类型变量(比如数组,对象),就会共享该引用类型的数据;
4、递归必须向退出递归的条件逼近,否则就是无限递归(栈溢出),出现StackOverflowError;
5.当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

/*
猴子吃桃子问题:有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!
以后每天猴子都吃其中的一半,然后再多吃一个。当到第10天时,
想再吃时(即还没吃),发现只有1个桃子 了。问题:最初共多少个桃子?
*/
public class Recursion{
	public static void  main(String[] args){
		T t = new T();
		int re = t.add(1);
		System.out.println("结果是"+ re);
	}
}
class T{
	public int add(int n){
		if(n>=10){
			return 1; 
		}else if(n>0 && n<10){
			return (add(n+1)+1)*2;
		}
		return -1;
	}
}

老鼠走迷宫

  1. findWay方法就是专内来找出迷宫的路径
  2. 如果找到,就返回true, 否则返回false
  3. map就是二维数组,即表示迷宫
  4. i,j 就是老鼠的位置,初始化的位置为(1,1)
  5. 因为我们是递归的找路,所以我先规定map数组的各个值的含义
  6. 0表示可以走1表示障碍物2表示可以走3表示走过,但是走不通是死路
  7. 当map[6][5] =2就说明找到通路, 就可以结束,否则就继续找.
public class Recursion{
	public static void  main(String[] args){
		int[][] map = new int[8][7];
		for(int i=0;i<7;i++){
			map[0][i] = 1;
			map[7][i] = 1;
		}
		for(int i=0;i<8;i++){
			map[i][0] = 1;
			map[i][6] = 1;
		}
		map[3][1]= 1;
		map[3][2]= 1;
		//输出当前的地图
		System.out.println("=====当前地图情况======" );
		for(int i=0;i<map.length;i++){
			for(int j=0;j<map[i].length;j++){
				System.out.print(map[i][j]+ " ");//输出一行
			}
			System.out.println();
		}
		//使用findWay给老鼠找路
		T t = new T();
		t.findWay(map, 1, 1);

		System.out.println("\n====找路的情况如下=====");
		for(int i=0;i< map.length;i++){
			for(int j=0;j<map[i].length;j++){
				System.out.print(map[i][j]+" ");//输出一行
			}
			System.out.println();
		}
	}
}
class T{
	public boolean findWay(int[][] map,int i , int j){
		if(map[6][5]==2){
			return true;	
		}else{
			if(map[i][j]==0){
				map[i][j]=2;
				if(findWay(map,i+1,j)){ //先走下面
					return true;
				}else if(findWay(map,i,j+1)){ //右
					return true;
				}else if(findWay(map,i-1,j)){ //上
					return true; 
				}else if(findWay(map,i,j-1)){ //左
					return true;
				}else{
					map[i][j] = 3;
					return false;
				}
			}else{
				return false;
			}
		}
	}
}

在这里插入图片描述

汉诺塔问题——用递归思想解决

class Tower {
	//方法
	//num 表示要移动的个数,a, b, C分别表示A塔,B塔,C塔
	public void move(int num,char a, char b ,char c) {
		//如果只有一个盘num = 1
		if(num==1){
		System,out. println(a + "->+ c);
		} else {
			//如果有多个盘,可以看成两个,最下面的和,上面的所有盘(num-1)
			//(1)先移动上面所有的盘到b,借助C
			move(num-1,a, C, b);
			//(2)把最下面的这个盘,移动到C
			System . out。println(a +"->+ c);
			//(3)再把b塔的所有盘,移动到C ,借助a
			move(num-1, b, a, c);
		}
	}
}

八皇后问题:
在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同 一列或同一斜线上,问有多少种摆法。思路:

  1. 第一个皇后先放第一行第一列
  2. 第二个皇后放在第二行第一列、 然后判断是否0K,如果不OK,继续放在第二二列、第三列、依次把所有列都放完,找到一个合适
  3. 继续第三个皇后,还是第一列、第二列…直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解
  4. 当得到一个正确解时,在栈回退到.上一个栈时,就会开始回溯,即将第一个皇后,放到第一-列的所有正确解,全部得到.
  5. 然后回头继续第一个皇后放第二列,后面继续循环执行1,2,3,4的步骤**

说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题. arr[8] = {0, 4, 7, 5,2, 6, 1,3} //对应arr下标表示第几行,即第几个皇后,arr[] = val, val表示第i+1个皇后,放在第i+1行的第val+1列

4.4、方法重载(略)

4.5、可变参数

java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
●基本语法
访问修饰符 返回类型 方法名(数据类型.….形参名){ }
注意事项和使用细节

  1. 可变参数的实参可以为0个或任意多个。
  2. 可变参数的实参可以为数组。
  3. 可变参数的本质就是数组.
  4. 可变参数可以和普通类型的参数-起放在形参列表,但必须保证可变参数在最后
    public void f2(String str, double. .. nums) {}
  5. 一个形参列表中只能出现一个可变参数
//1. int...表示接受的是可变参数,类型是int ,即可以接收多个int(0-多)
//2.使用可变参数时,可以当做数组来使用即nums可以当做数组
//3.逼历nums求和即可
public class test {
    public static void main(String[] args) {
		int res=0;
        te t = new te();
		res=t.sum(1,2,3,4,5,6);
		//这里也可以传一个数组进去int[] arr = {1,2,3,4,5,6};
		//res = t.sum(arr);
		System.out.println("和为"+res);//21
    }
}
class te{
	public int sum(int... nums){
		System.out.println("接收的参数个数="+ nums.length);
		int res = 0;
		for(int i = 0;i < nums.length; i++) {
			res += nums[i];
		}
		return res;
	}
}

4.6、变量作用域

  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量。
  2. 我们说的局部变量一般是指在成员方法中定义的变量。【举例Cat类: cry】
  3. java中作用域的分类
    全局变量:也就是属性,作用域为整个类体 Cat类:cry eat等方法使用属性
    局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!
  4. 全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使
    用,因为没有默认值

注意事项和细节使用

  1. 属性(全局变量)和局部变量可以重名,访问时遵循就近原则。
  2. 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
  3. 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中生效。
  4. 作用域范围不同
    全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
    局部变量:只能在本类中对应的方法中使用
  5. 修饰符不同
    全局变量/属性可以加修饰符
    局部变量不可以加修饰符

4.7、匿名对象

class A{
	System.out.println("匿名对象");
}
public class Test{
	new A();//创建匿名对象,用完,内存清空,无法再次使用。
}

5、构造器

  1. 一个类可以定义多个不同的构造器,即构造器重载 比如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名,不需要指定年龄
  2. 构造器名和类名要相同
  3. 构造器没有返回值
  4. 构造器是完成对象的初始化.并不是创建对象
  5. 在创建对象时,系统自动的调用该类的构造方法
  6. 如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如Person (){},使用javap指令反编译看看
  7. 一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下,即: Person (){}.
public class test{
	String name;
	int age;
	public test(){//无参构造
	}
	public test(String name,int age){//有参构造
		this.name = name;
		this.age = age;
	}
}

流程分析
1.加载Person类信息(Person.class),只会加载一次2.在堆中分配空间(地址)
3.完成对象初始化[3.1 默认初始化 age=0 name=null 3.2显式初始化age=90,name=null,3.3构造器的初始化 age =20, name=小倩]
4.在对象在堆中的地址,返回给p(p是对象名,也可以理解成是对象的引用)在这里插入图片描述

5.1、this关键字

this可以理解为每一个对象空间会隐藏一个this并指向对象自身的地址。

this的注意事项和使用细节

  1. this关键字可以用来访问本类的属性、方法、构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员方法的语法:this.方法名(参数列表);
  4. 访问构造器语法:this(参数列表);注意只能在构造器中使用且在Java中,这被称为构造函数的链式调用或构造函数的重载调用。但是这种调用应该出现在构造函数的第一行,而不是在中间或者最后。
  5. this不能在类定义的外部使用,只能在类定义的方法中使用。
public class ex{
	public static void main(String[] args){
		Test test = new Test();
		test.info("jack",18);
		//test是一个对象,他指向堆中info方法的地址
		//这里info的this指向的就是这个当前对象test的属性。
	}
}
class Test{
	String name;
	int age;
	public Test(){//无参构造
	}
	public info(String name,int age){
		this.name = name; //this表示当前对象的属性
		this.age = age;
	}
}

class T {
//细节:访问成员方法的语法: this.方法名(参数列表);
	public void f1() {
		System.out.println("f1()方法..");
	}
	public void f2() {
		System . out . println("f2()方法..");
		//调用本类的f1
		//第1种方式
		f1();I
		//第2种方式
		this.f1();
	}
}

在这里插入图片描述

//细节:访问构造器的语法: this(参数列表);
public class Test
{
   public static void main(String[] args) {
		 new info();
	}
}
class info {  
   public info() {  
   		//对this的调用必须是构造器中的第一个语句
        this("tom", 16, 50); //调用其他构造函数  
		System.out.println("无参构造输出");  
   }  
   public info(String name, int age, int weight) {  
       System.out.println(name + age + weight);  
   }  
}

注意:
在这里插入图片描述

第二阶段

在这里插入图片描述

1、包

包的三大作用:

  1. 区分相同名字的类
  2. 当类很多时,可以很好的管理类
  3. 控制访问范围

基本语法:package packName;
包的本质实际上就是创建不同的文件夹来保存类文件。
如果在src目录下创建包名为com.new,则在文件夹下会产生一个com文件夹和一个new文件夹,在这个包下的类全部储存在new文件里。

2、访问修饰符

访问级别访问控制修饰符同类同包子类不同包
公开public
受保护protected×
默认没有修饰符××
私有private×××

注意事项:

  1. 修饰符可以用来修饰类中的属性,成员方法以及类
  2. 只有默认的和public才能修饰类!,并且遵循上述访问权限的特点。
  3. 因为没有学习继承,因此关于在子类中的访问权限,我们讲完子类后,在回头讲解
  4. 成员方法的访问规则和属性完全一样.

3、封装

封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
封装的理解和好处:

  1. 隐藏实现细节:方法(例如连接数据库)<–调用(传入参数…)2)可以对数据进行验证,保证安全合理
    在这里插入图片描述

4、继承

类与类之间的属性和方法很多都相同,说明可以代码复用——继承(extends
在这里插入图片描述

//继承:子类拥有了父类的属性和方法
class zi extends fu{
}

4.1、继承的深入讨论和细节问题

注意:

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以被访问,但是私有属性不能在子类直接访问,要通过父类提供的公共的方法去访问**
  2. 子类必须要调用父类的构造器super(),完成父类的初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
  4. 如果希望指定去调用父类的某个构造器(假设存在多个构造器的情况下),则显式的调用一下: super(参数列表)
  5. super在使用时, 必须放在构造器第一行,super只能在构造器中使用
  6. super() 和 this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
  7. java所有类都是Object类的子类,Object是所有类的父类
  8. 父类构造器的调用不限于父类!将一直往上追溯直到Object类(顶级父类)
    在这里插入图片描述
  9. 子类最多只能继承一个父类(指直接继承), 即java中是单继承机制。
    思考:如何让A类继承B类和C类? [让A继承B,B再继承C ]
  10. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系(猫是动物)

继承的本质分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试
在这里插入图片描述

5、super

基本介绍
super代表父类的引用,用于访问父类的属性、方法、构造器基本语法

  1. 访问父类的属性,但不能访问父类的private属性[案例] super.属性名
  2. 访问父类的方法,不能访问父类的private方法 super.方法名(参数列表);
  3. 访问父类的构造器(这点前面用过): super(参数列表);
  4. 只能放在构造器的第一句,只能出现一句!

细节:
在这里插入图片描述
super.方法名 这种调用是直接访问父类的方法,即使子类有这个方法,也不会调用,如果父类没有,则继续往上找,跳过本类

super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则
在这里插入图片描述

6、overwrite(方法重写/覆盖)

基本介绍:方法覆盖(重写)就是子类有一个方法,和父类(可能是多级基类)的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
注意事项和使用细节
方法重写也叫方法覆盖,需要满足下面的条件

  1. 子类的方法的形参列表,方法名称,要和父类方法的参数,方法名称完全一样。
  2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类比如父类返回类型是Object ,子类方法返回类型是String
    public object getInfo(){}
    public String getInfo(){}
  3. 子类方法不能缩小父类方法的访问权限,但可以在子类扩大父类方法的权限
    public > protected >默认> private
    void sayOk(){ }
    public void sayOk(){}

在这里插入图片描述
在这里插入图片描述

7、多态

文件 package practive.ploy1;

多[多种]态[状态]基本介绍: 方法或对象具有多种形态。是面向对象的第3三大特征,多态是建立在封装和继承基础之上的。
多态的具体体现

  1. 方法的多态
    重写和重载就体现多态[PloyMethod ]

多态的具体体现

  1. 对象的多态(核心,困难,重点)

重要的几句话:
(1) 一个对象的编译类型和运行类型可以不一致
(2) 编译类型在定义对象时,就确定了,不能改变
(3) 运行类型是可以变化的.
(4) 编译类型看定义时=号的左边,运行类型看=号的右边
Animal animal = new Dog(); 【animal编译类型是Animal,运行类型Dog】animal = new Cat();【animal的运行类型变成了Cat,编译类型仍然是 Animal】
在这里插入图片描述

向上转型:父类的引用指向了子类的对象

  1. 语法:父类类型引用名 = new子类类型();
  2. 可以调用父类中的所有成员(需遵守访问权限)
  3. 但是不能调用子类的特有的成员 因为在编译阶段,能调用哪些成员,是由编译类型来决定的
  4. 最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类开始查找方法然后调用,规则我前面我们讲的方法调用规则一致。
public class Test {
    public static void main(String[] args) {
        //向上转型:父类的引用指向了子类的对象
        // 语法:父类类型引用名 = new子类类型();
        Animal animal = new Cat();

        //可以调用父类中的所有成员(需遵守访问权限)
        //但是不能调用子类的特有的成员
        //因为在编译阶段,能调用哪些成员,是由编译类型来决定的
        //animal. catchMouse();错误
        //最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类开始查找方法
        //,然后调用,规则我前面我们讲的方法调用规则一致。
        animal.run();  //这里面的也是从Cat里面找是否有run方法,如果没有就往Animal父类里面找
        animal.eat();
        animal.show();
        animal.sleep();
        //animal.catchMouse();发生错误   不能调用子类的特有的成员
    }
}
public class PloMethod{
	public static void main(String[] args){
	//方法重载体现多态
	A a = new A();
	//这里我们传入不同的参数,就会调用不同sum方法,就体现多态
	System.out.pringtln(a.sum(10,20));
	System.out.pringtln(a.sum(10,20,30));
	
	//方法重写体现多态
	B b = new B();
	a.say();
	b.say();
	}
}

class B{//父类
	public void say(){
		System.out.pringtln("B say()方法调用");
	}
class A extends B{//子类
	public int sum(int n1,int n2){
		return n1+n2;
	}
	public int sum(int n1,int n2,int n3){
		return n1+n2+n3;
	}
	public void say(){
		System.out.pringtln("A say()方法调用");
	}
}

多态注意事项和细节讨论
多态的向下转型

  1. 语法:子类类型 引用名= (子类类型) 父类引用;
  2. 只能强转父类的引用,不能强转父类的对象
  3. 要求父类的引用必须指向的是当前目标类型的对象 4)可以调用子类类型中所有的成员

在这里插入图片描述
属性值看编译类型,方法调用看运行类型

class Animal {
    String sound = "Some sound";

    void makeSound() {
        System.out.println(sound);
    }
}

class Dog extends Animal {
    Dog() {
        sound = "Bark";
    }

    @Override
    void makeSound() {
        System.out.println(sound);
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 多态
        System.out.println(animal.sound); // 编译时类型 Animal,输出 "Some sound"
        animal.makeSound(); // 运行时类型 Dog,输出 "Bark"
    }
}

7.1、动态绑定机制

java的动态绑定机制

  1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
  2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
    在这里插入图片描述
    1、 在上述代码中输出会是40和30
    2、 在子类中去掉sum()方法,则在主方法中运行时在子类中找不到会继续往父类中寻找,其中getI()方法根据动态绑定机制会根据运行类型找到getI()方法,所以找到的是class B中的getI()再加上10即a.sum()结果是20+10=30
    3、 如果在子类中去掉sum1()方法,根据属性没有动态绑定机制,父类中的sum1()中的i+1为10+10=20

7.2、多态数组

定义:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

//应用实例:现有一个继承结构如下:要求创建1个Person对象、2个Student 对象和
//2个Teacher对象,统- -放在数组中,并调用say方法
package Test1;

public class Person {
	private int age;
	private String name;
	public Person(String name,int age) {
		super();
		this.age = age;
		this.name = name;
	}
	public Person() {}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String say() {
		return age +"\t"+  name;
	}

}

package Test1;

public class Student extends Person{
	private double score;

	public Student(int age, String name, double score) {
		super(name,age);
		this.score = score;
	}

	public double getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}
	
	public String say() {
		return super.say()+"\t"+"score="+score;
	}
}

package Test1;

public class Teacher extends Person{
	private double salary;

	public Teacher(int age , String name,double salary) {
		super(name , age);
		this.salary = salary;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	public String say() {
		return super.say()+"\t"+"salary = "+salary;
	}
}
package Test1;

public class PolyArray {
	public static void main(String[] args) {
		Person[] person = new Person[5];
		person[0] = new Person("jack",20);
		person[1] = new Student(22,"Tom",100);
		person[2] = new Student(18,"smith",82);
		person[3] = new Teacher(33,"scotter",8000);
		person[4] = new Teacher(45,"jack",18000);
		
	
		for(int i = 0;i<5;i++) {
			System.out.println(person[i].say());//动态绑定机制
		}
	}
}
//  20	jack
//  22	Tom	     score=100.0
//  18	smith	score=82.0
//  33	scotter	salary = 8000.0
//  45	jack	salary = 18000.0

8、object类详解

8.1、equals方法

"=="和equals的对比
== :既可以判断基本类型,又可以判断引用类型
== :如果判断基本类型,判断的是值是否相等。示例: int i= 10; double d= 10.0;
== :如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象

A a = new A();
A b = a;
A C = b;
System.out.println(a == c);//true
System.out.printLn(b == c);//true

equals: 是Object类中的方法, 只能判断引用类型
默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如Integer,String

9、断点调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值