21.2.8-21.2.17Java学习记录

Java基础学习总结

21.2.8

Java基础- - - - - - 匿名对象

匿名对象

  • 匿名对象:我们创建的对象,没显式的赋给一个变量名。即为匿名对象
  • 特点:匿名对象只能调用一次
  • 举例:
new Phone().sendEmail();
		new Phone().playGame();	
		new Phone().price = 1999;
		new Phone().showPrice();//0.0
  • 应用场景:
PhoneMall mall = new PhoneMall();

//匿名对象的使用
mall.show(new Phone());

class PhoneMall{
	public void show(Phone phone){
		phone.sendEmail();
		phone.playGame();
	}
	
}

Java基础- - - - - - 可变个数形参

  • 格式:
JDK5.0以前:数据类型[] 变量名
public void show(String[] strs){	
	
	}

JDK5.0以后:数据类型 ... 变量名
public void show(String ... strs){
	
		}

注意:同一个类中两则不能共存
  • 可变个数形参在方法的形参中,必须声明在末尾
  • 可变个数形参在方法的形参中,最多只能声明一个可变形参

Java基础- - - - - - 方法参数的值传递机制

  • 规则:

    • 如果参数基本数据类型,此时实参赋给形参的是实参真实存储的数据值
    • 如果参数引用数据类型,此时实参赋给形参的是实参存储数据的地址值
  • 推广:

    • 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
    • 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
  • 注意点1:

public class ValueTransferTest1 {
	public static void main(String[] args) {
		
		int m = 10;
		int n = 20;
		
		System.out.println("m = " + m + ", n = " + n);
		//交换
		
		ValueTransferTest1 test = new ValueTransferTest1();
		test.swap(m, n);
		
		System.out.println("m = " + m + ", n = " + n);
			
	}
		
	public void swap(int m,int n){
		int temp = m ;
		m = n;
		n = temp;
	}
}

编译结果:没换成功
在这里插入图片描述
原因:交换的是·swap方法中的值,main方法中并没有交换
在这里插入图片描述

  • 注意点2:
public class ValueTransferTest2 {
	
	public static void main(String[] args) {
		
		Data data = new Data();
		
		data.m = 10;
		data.n = 20;
		
		System.out.println("m = " + data.m + ", n = " + data.n);
	
		ValueTransferTest2 test = new ValueTransferTest2();
		test.swap(data);
		
		
		System.out.println("m = " + data.m + ", n = " + data.n);
		
	}
	
	public void swap(Data data){
		int temp = data.m;
		data.m = data.n;
		data.n = temp;
	}
	
}

class Data{
	
	int m;
	int n;
	
}

编译结果:换成功在这里插入图片描述
原因:参数是引用数据类型,传递的是地址值,指向同一个对象
在这里插入图片描述

  • 练习:
    在这里插入图片描述
    在这里插入图片描述
    答案:15,0,20

21.2.9

Java基础- - - - - - 递归方法的使用

  • 1.定义:一个方法体内调用它自身。
  • 2.如何理解递归方法?
    • 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
    • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
  • 举例:

例1:计算1-n之间所有自然数的和

public int getSum(int n) {
		if(n == 1) {
			return 1;
		}else {
			return n+ getSum(n-1);
		}
	}

例2:计算1-n之间所有自然数的乘积:n!

public int getSum1(int n) {

		if (n == 1) {
			return 1;
		} else {
			return n * getSum1(n - 1);
		}
	}

Java基础- - - - - - Java规定的四种权限修饰符

在这里插入图片描述

  • 4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
  • 修饰类的话,只能使用:缺省、public
1:缺省
class Person{

}
2public
publlic class Demo{

}

Java基础- - - - - - UML类图

在这里插入图片描述

Java基础- - - - - - this关键字

  • this调用属性、方法
  • this调用构造器
    • 使用"this(形参列表)"方式
    • 构造器中不能通过"this(形参列表)"方式调用自己
    • 构造器中不能通过"this(形参列表)"方式调用自己
    • 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
      在这里插入图片描述

Java基础- - - - - - Eclipse中的快捷键:

  • 1.补全代码的声明:alt + /
  • 2.快速修复: ctrl + 1
  • 3.批量导包:ctrl + shift + o
  • 4.使用单行注释:ctrl + /
  • 5.使用多行注释: ctrl + shift + /
  • 6.取消多行注释:ctrl + shift + \
  • 7.复制指定行的代码:ctrl + alt + down 或 ctrl + alt + up
  • 8.删除指定行的代码:ctrl + d
  • 9.上下移动代码:alt + up 或 alt + down
  • 10.切换到下一行代码空位:shift + enter
  • 11.切换到上一行代码空位:ctrl + shift + enter
  • 12.如何查看源码:ctrl + 选中指定的结构 或 ctrl + shift + t
  • 13.退回到前一个编辑的页面:alt + left
  • 14.进入到下一个编辑的页面(针对于上面那条来说的):alt + right
  • 15.光标选中指定的类,查看继承树结构:ctrl + t
  • 16.复制代码: ctrl + c
  • 17.撤销: ctrl + z
  • 18.反撤销: ctrl + y
  • 19.剪切:ctrl + x
  • 20.粘贴:ctrl + v
  • 21.保存: ctrl + s
  • 22.全选:ctrl + a
  • 23.格式化代码: ctrl + shift + f
  • 24.选中数行,整体往后移动:tab
  • 25.选中数行,整体往前移动:shift + tab
  • 26.在当前类中,显示类结构,并支持搜索指定的方法、属性等:ctrl + o
  • 27.批量修改指定的变量名、方法名、类名等:alt + shift + r
  • 28.选中的结构的大小写的切换:变成大写: ctrl + shift + x
  • 29.选中的结构的大小写的切换:变成小写:ctrl + shift + y
  • 30.调出生成getter/setter/构造器等结构: alt + shift + s
  • 31.显示当前选择资源(工程 or 文件)的属性:alt + enter
  • 32.快速查找:参照选中的Word快速定位到下一个 :ctrl + k
  • 33.关闭当前窗口:ctrl + w
  • 34.关闭所有的窗口:ctrl + shift + w
  • 35.查看指定的结构使用过的地方:ctrl + alt + g
  • 36.查找与替换:ctrl + f
  • 37.最大化当前的View:ctrl + m
  • 38.直接定位到当前行的首位:home
  • 39.直接定位到当前行的末位:end

21.2.10

Java基础- - - - - - 练习题(注意点)

1:注意方法的调用次序,以及要画图

public class Test{ 
public static void leftshift(int i, int j){ 
        i+=j; 
        System.out.println(i); //6
} 
public static void main(String args[]){ 
int i = 4, j = 2; 
leftshift(i, j); 
System.out.println(i); //4
} 
} 


答案:
4.  和leftShift函数没关系。
  • List item

21.2.12

Java基础- - - - - - Eclipse_Debug调试

1:Debug不能打开界面问题解决

Bug解决|Eclipse点击Debug没有弹出Debug视图
2:Debug界面Variables显示问题
Window—Show view----other----Debug
在这里插入图片描述
3:如何调试

  • 设置断点(注意:可以设置多个断点)
  • debug as java application
  • 常用操作
    在这里插入图片描述在这里插入图片描述

Java基础- - - - - - 多态性(向下转型)

  • 1:理解:Man man = new Man();
    有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的但是由于变量声明为父类类型导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。?如何才能调用子类特的属性和方法?使用向下转型。
  • 2:如何实现向下转型:
    使用强制类型转换符:()
Person p2 = new Man();
//如何才能调用子类特有的属性和方法?
//向下转型:使用强制类型转换符。
Man m1 = (Man)p2;
//强转后,就可以调用子类特有的方法
m1.earnMoney();
m1.isSmoking = true;

在这里插入图片描述

  • 3:使用时的注意点:
    ① 使用强转时,可能出现ClassCastException的异常。
    为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型
  • 4:instanceof的使用:
    ① a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
    ② 如果 a instanceof A返回true,则 a instanceof B也返回true.其中,类B是类A的父类。
    ③ 要求a所属的类与类A必须是子类和父类的关系,否则编译错误。
if(p2 instanceof Woman){
	Woman w1 = (Woman)p2;
	w1.goShopping();
	System.out.println("******Woman******");
}
		
if(p2 instanceof Man){
	Man m2 = (Man)p2;
	m2.earnMoney();
	System.out.println("******Man******");
}

Java基础- - - - - - 多态性(实例变量例子)

  • 1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边
  • 2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
    举例:
    在这里插入图片描述

Java基础- - - - - - 多态性(虚拟方法调用)

在这里插入图片描述

Java基础- - - - - - 父类未定义空参构造器,子类…

  • 父类在定义了有参构造器的同时,未显式定义空参构造器的情况下。
    在定义子类时,由于没有空参构造器继承,在不定义有参构造器的情况下,必须显式的定义一个空参构造器,否则会编译错误。

Java基础- - - - - - 多态性(子父类中int… arr和int[] arr)

在这里插入图片描述

Java基础- - - - - - java.lang.Object类常用方法(equals()、toString())

equals()的使用:

  • 是一个方法,而非运算符

  • 只能适用于引用数据类型
    在这里插入图片描述

  • Object类中equals()的定义:

 public boolean equals(Object obj) {
	        return (this == obj);
 }

说明:Object类中定义的equals()和==的作用是相同的:
比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体

通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写.

  • 重写的原则:==比较两个对象的实体内容==是否相同
  • 注意:像String、Date、File、包装类等都重写了Object类中的equals()方法
    在这里插入图片描述

如何手动重写equals()

package com.atguigu.java1;

public class Customer {
	
	private String name;
	private int age;
	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 Customer() {
		super();
	}
	public Customer(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	//重写的原则:比较两个对象的实体内容(此举例即:name和age)是否相同
	public boolean equals1(Object obj) {
		
		//如果当前对象和形参引用地址值一样,直接返回true
		if (this == obj) {
            return true;
        }
		//判断形参obj是否是Customer的实例
		if(obj instanceof Customer){
			//如果obj是Customer的实例,将obj强转成Customer类型
			Customer cust = (Customer)obj;
			//比较两个对象的每个属性是否都相同
			//此例中age是基本数据类型,故用==比较,但name是引用数据类型,需要用equals()比较
			if(this.age == cust.age && this.name.equals(cust.name)){
				return true;
			}else{
				return false;
			}
			
//			//或
//			return this.age == cust.age && this.name.equals(cust.name);
		}else{
			return false;
			
		}
		
	}

如何自动重写equals()
Source---->Generate HashCode and equals---->
在这里插入图片描述
重写equals()练习

/*
 * 编写Order类,有int型的orderId,String型的orderName,
 * 相应的getter()和setter()方法,两个参数的构造器,
 * 重写父类的equals()方法:public boolean equals(Object obj),
 * 并判断测试类中创建的两个对象是否相等。

 */
public class OrderTest {
	public static void main(String[] args) {
		Order o1 = new Order(23, "Tom");
		Order o2 = new Order(23, "Tom");
		System.out.println(o1 == o2);//false
		System.out.println(o1.equals(o2));//true(重写过,故比较的是实体内容 )
	}
}


class Order{
	private int orderId;
	private String orderName;
	
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	public Order(int orderId, String orderName) {
		super();
		this.orderId = orderId;
		this.orderName = orderName;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof Order) {
			Order order = (Order)obj;
			if(this.orderId == order.orderId && this.orderName.equals(order.orderName)) {
				return true;
			}else {
				return false;
			}
		}
		return false;
	}
}

public class MyDateTest {
	public static void main(String[] args) {
        MyDate m1 = new MyDate(14, 3, 1976);
        MyDate m2 = new MyDate(14, 3, 1976);
        if (m1 == m2) {
            System.out.println("m1==m2");
        } else {
            System.out.println("m1!=m2"); // m1 != m2
        }

        if (m1.equals(m2)) {
            System.out.println("m1 is equal to m2");// m1 is equal to m2
        } else {
            System.out.println("m1 is not equal to m2");
        }
    }

}

class MyDate{
	private int day;
	private int month;
	private int year;
	
	public MyDate(int day, int month, int year) {
		super();
		this.day = day;
		this.month = month;
		this.year = year;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		
		if(obj instanceof MyDate){
			MyDate myDate = (MyDate)obj;
			return this.day == myDate.day && this.month == myDate.month &&
					this.year == myDate.year;
		}
		
		return false;

	}
//自动重写
//	@Override
//	public boolean equals(Object obj) {
//		if (this == obj)
//			return true;
//		if (obj == null)
//			return false;
//		if (getClass() != obj.getClass())
//			return false;
//		MyDate other = (MyDate) obj;
//		if (day != other.day)
//			return false;
//		if (month != other.month)
//			return false;
//		if (year != other.year)
//			return false;
//		return true;
//	}
	
	
}

toString()的使用:

  • Object类中toString()的定义:
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
     }
  • 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
  • 像String、Date、File、包装类等都重写了Object类中的toString()方法。使得在调用对象的toString()时,返回"实体内容"信息
  • 自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"

在这里插入图片描述

  • 采用自动重写实现即可

21.2.13

c
为了使基本数据类型的变量具有类的特征,引入包装类

基本数据类型与对应的包装类:
在这里插入图片描述
基本数据类型、包装类、String三者之间的相互转换

  • 基本数据类型<—>包装类JDK 5.0 新特性:自动装箱 与自动拆箱
@Test
	public void test3(){

		//自动装箱:基本数据类型 --->包装类
		int num2 = 10;
		Integer in1 = num2;//自动装箱
		
		boolean b1 = true;
		Boolean b2 = b1;//自动装箱
		
		//自动拆箱:包装类--->基本数据类型
		System.out.println(in1.toString());
		
		int num3 = in1;//自动拆箱
		
	}
	
  • 基本数据类型、包装类—>String
    • 调用String重载的valueOf(Xxx xxx)
    • 连接运算
@Test
	public void test4(){
		
		int num1 = 10;
		//方式1:连接运算
		String str1 = num1 + "";
		//方式2:调用String的valueOf(Xxx xxx)
		float f1 = 12.3f;
		String str2 = String.valueOf(f1);//"12.3"
		
		Double d1 = new Double(12.4);
		String str3 = String.valueOf(d1);
		System.out.println(str2);
		System.out.println(str3);//"12.4"
		
	}

String—>基本数据类型、包装类调用包装类的parseXxx(String s)

@Test
	public void test5(){
		String str1 = "123";
		//错误的情况:
//		int num1 = (int)str1;
//		Integer in1 = (Integer)str1;
		//可能会报NumberFormatException
		int num2 = Integer.parseInt(str1);
		System.out.println(num2 + 1);
		
		String str2 = "true";
		boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);//true
		
		String str3 = "true1";
		boolean b2 = Boolean.parseBoolean(str3);
		System.out.println(b2);//false(非true就是false)
	}

Java基础- - - - - - 包装类(面试题:)

题一:知识点(编译时类型相同,自动类型提升)
在这里插入图片描述
解题:
在这里插入图片描述
题二:知识点(Integer包装类中-128~127范围的整数地址在相同)

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

Java基础- - - - - - 包装类(练习题)

import java.util.Scanner;
import java.util.Vector;

/*
 *  利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
	提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。
	而向量类java.util.Vector可以根据需要动态伸缩。
	
	创建Vector对象:Vector v=new Vector();
	给向量添加元素:v.addElement(Object obj);   //obj必须是对象
	取出向量中的元素:Object  obj=v.elementAt(0);
	注意第一个元素的下标是0,返回值是Object类型的。
	计算向量的长度:v.size();
	若与最高分相差10分内:A等;20分内:B等;
	      30分内:C等;其它:D等

 * 
 * 
 * 
 * 
 */
public class ScoreTest {
	public static void main(String[] args) {
		//1.实例化Scanner,用于从键盘获取学生成绩
		Scanner scan = new Scanner(System.in);
		
		//2.创建Vector对象:Vector v=new Vector();相当于原来的数组
		Vector v = new Vector();
		
		//3.通过for(;;)或while(true)方式,给Vector中添加数组
		int maxScore = 0;
		for(;;){
			System.out.println("请输入学生成绩(以负数代表输入结束)");
			int score = scan.nextInt();
			//3.2 当输入是负数时,跳出循环
			if(score < 0){
				break;
			}
			if(score > 100){
				System.out.println("输入的数据非法,请重新输入");
				continue;
			}
			//3.1 添加操作::v.addElement(Object obj)
			//jdk5.0之前:
//			Integer inScore = new Integer(score);
//			v.addElement(inScore);//多态
			//jdk5.0之后:
			v.addElement(score);//自动装箱
			//4.获取学生成绩的最大值
			if(maxScore < score){
				maxScore = score;
			}
		}
		
		//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
		char level;
		for(int i = 0;i < v.size();i++){
			Object obj = v.elementAt(i);
			//jdk 5.0之前:
//			Integer inScore = (Integer)obj;
//			int score = inScore.intValue();
			//jdk 5.0之后:
			int score = (int)obj;
			
			if(maxScore - score <= 10){
				level = 'A';
			}else if(maxScore - score <= 20){
				level = 'B';
			}else if(maxScore - score <= 30){
				level = 'C';
			}else{
				level = 'D';
			}
			
			System.out.println("student-" + i + " score is " + score + ",level is " + level);
			
		}		
		
	}
}

知识点;

  • continue:结束本次循环,会重新开始下一次循环
  • break;结束循环。

Java基础- - - - - - 重写规则(返回值类型)

返回值类型:

  • 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
  • 父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
  • 父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)

21.2.14

Java基础- - - - - - 构造器调用 ( “父先行”)

当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前先执行,不仅如此,执行父类构造器时,系统会再次上溯执行其父类构造器…以此类推,创建任何Java对象,最先执行的总是Java,lang,Object类的构造器

Java基础- - - - - - 单例设计模式

饿汉式提前造好对象

public class SingletonTest1{
	public static void main(String[] args){
		Bank bank1 = Bank.getInstance();
		Bank bank2 = Bank.getInstance();
		System.out.println(bank1 == bank2);//true
	}
}
//饿汉式
class Bank{
	//1.私有化类的构造器
	private Bank(){
		
		
	}
	//2.内部创建类的对象,要求此对象必须声明为静态的
	private static Bank instance = new Bank();
	//3.提供公共的静态方法,返回类的对象
	public static Bank getInstance() {
		return instance;
	}

}

懒汉式什么时候用什么时候造对象

public class SingletonTest2{
	public static void main(String[] args){
		Order order1 = Order.getInstance();
		Order order2 = Order.getInstance();
		
		System.out.println(order1 == order2);//true
	}
}

//懒汉式
class Order{
	//1.私有化类的构造器
	private Order(){
		
		}
	//声明当前类的对象,没有初始化,此对象必须声明为static
	private static Order instance = null;
	
	//3.声明public、static的返回当前类对象的方法
	public static Order getInstance(){
		//是null说明还没有创建对象
		if(instance == null){
			instance = new Order();
			
		}
		return instance;
	}
	
}

两者对比:

  • 饿汉式:坏处,对象加载过长。好处,线程安全的
  • 懒汉式:好出,延迟对象的创建。目前这种写法,线程是不安全的

Java基础- - - - - - 实例化子类对象时,涉及到父类、子类中静态代码块、非静态代码块、构造器的加载顺序(由父及子,静态先行)

在这里插入图片描述

# 21.2.15

Java基础- - - - - - 自动获取当前的时间(年、月、日)

		//获取当前月份
		Calendar calendar = Calendar.getInstance();
		int month = calendar.get(Calendar.MONTH);//注意:1月份是0
		//获取当前年份
		Calendar calendar = Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		System.out.println(year);
		//获取本月天数(今日是本月的第几天)
		Calendar calendar = Calendar.getInstance();
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		System.out.println(day);
		//获取本周天数(今日是本周的第几天)
		Calendar calendar = Calendar.getInstance();
		int day = calendar.get(Calendar.DAY_OF_WEEK);
		System.out.println(day);

Java基础- - - - - - 匿名子类的对象、匿名子类的匿名对象

abstract class Creature{
	public abstract void breath();
}
abstract class Person extends Creature{
	String name;
	int age;
	
	public Person(){
		
	}
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	//抽象方法
	public abstract void eat();
	
	public void walk(){
		System.out.println("人走路");
	}
	
	
}
//继承Person抽象类,并实现了抽象方法
class Student extends Person{
	
	public Student(String name,int age){
		super(name,age);
	}
	public Student(){
	}
	
	public void eat(){
		System.out.println("学生多吃有营养的食物");
	}

	@Override
	public void breath() {
		System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
	}
}
public class PersonTest {
	
	public static void main(String[] args) {
		
		method(new Student());//匿名对象
		
		Worker worker = new Worker();
		method1(worker);//非匿名的类非匿名的对象
		
		method1(new Worker());//非匿名的类匿名的对象
		
		System.out.println("********************");
		
		//创建了一匿名子类的对象:p
		Person p = new Person(){

			@Override
			public void eat() {
				System.out.println("吃东西");
			}

			@Override
			public void breath() {
				System.out.println("好好呼吸");
			}
			
		}; 
		
		method1(p);
		System.out.println("********************");
		//创建匿名子类的匿名对象
		method1(new Person(){
			@Override
			public void eat() {
				System.out.println("吃好吃东西");
			}

			@Override
			public void breath() {
				System.out.println("好好呼吸新鲜空气");
			}
		});
	}
	
	
	public static void method1(Person p){
		p.eat();
		p.breath();
	}
	
	public static void method(Student s){
		
	}
}

class Worker extends Person{

	@Override
	public void eat() {
	}

	@Override
	public void breath() {
	}
	
}

Java基础- - - - - - 接口的匿名实现类的非匿名对象、接口的匿名实现类的匿名对象

public class USBTest {
	public static void main(String[] args) {
		
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		com.transferData(flash);
		
		//2. 创建了接口的非匿名实现类的匿名对象
		com.transferData(new Printer());
		
		//3. 创建了接口的匿名实现类的非匿名对象
		USB phone = new USB(){

			@Override
			public void start() {
				System.out.println("手机开始工作");
			}

			@Override
			public void stop() {
				System.out.println("手机结束工作");
			}
			
		};
		com.transferData(phone);
		
		
		//4. 创建了接口的匿名实现类的匿名对象
		
		com.transferData(new USB(){
			@Override
			public void start() {
				System.out.println("mp3开始工作");
			}

			@Override
			public void stop() {
				System.out.println("mp3结束工作");
			}
		});
	}
}

class Computer{
	
	public void transferData(USB usb){//USB usb = new Flash();
		usb.start();
		
		System.out.println("具体传输数据的细节");
		
		usb.stop();
	}
	
	
}

interface USB{
	//常量:定义了长、宽、最大最小的传输速度等
	
	void start();
	
	void stop();
	
}

class Flash implements USB{

	@Override
	public void start() {
		System.out.println("U盘开启工作");
	}

	@Override
	public void stop() {
		System.out.println("U盘结束工作");
	}
	
}

class Printer implements USB{
	@Override
	public void start() {
		System.out.println("打印机开启工作");
	}

	@Override
	public void stop() {
		System.out.println("打印机结束工作");
	}
	
}


Java基础- - - - - - 代理模式(代理类、被代理类)

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

Java基础- - - - - - Java8中关于接口的新规范

  • JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
  • 接口中定义的静态方法,只能通过接口来调用
public interface CompareA {
	
	//静态方法
	public static void method1(){
		System.out.println("CompareA:北京");
	}
	//默认方法
	public default void method2(){
		System.out.println("CompareA:上海");
	}
	
	default void method3(){//public 可省略
		System.out.println("CompareA:上海");
	}
}

public class SubClassTest {
	
	public static void main(String[] args) {
		//知识点1:接口中定义的静态方法,只能通过接口来调用。
		CompareA.method1();
	
	}
	
}
  • 通过实现类的对象,可以调用接口中的默认方法。如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
public class SubClassTest {
	
	public static void main(String[] args) {
		SubClass s = new SubClass();
		//知识点2:通过实现类的对象,可以调用接口中的默认方法。
		//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
		s.method2();
	
}
  • 如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则
  • 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法
    • 那么在实现类没重写此方法的情况下,报错。–>接口冲突。
    • 这就需要我们必须在实现类中重写此方法
  • 在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
		method3();//调用自己定义的重写的方法
		super.method3();//调用的是父类中声明的
		//调用接口中的默认方法
		CompareA.super.method3();
		CompareB.super.method3();
	}

21.2.16

Java基础- - - - - - 静态方法(this关键字、super关键字)

  • 在静态的方法内,不能使用this关键字、super关键字,因为不需要实例就可以访问static方法,

Java基础- - - - - - 代码块(静态、非静态)

代码块的作用:

  • 用来初始化类、对象的信息

静态代码块:为静态属性赋值

  • 内部可以输出语句
  • 随着类的加载而执行,而且只执行一次
  • 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
  • 静态代码块的执行要优先于非静态代码块的执行
  • 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构

非静态代码块:为非静态属性赋值

  • 内部可以输出语句
  • 随着对象的创建而执行
  • 每创建一个对象,就执行一次非静态代码块
  • 作用:可以在创建对象时,对对象的属性等进行初始化
  • 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
  • 非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法

Java基础- - - - - - 内部类(成员内部类、局部内部类在编译以后,都会生成字节码文件)

  • 成员内部类:外部类$内部类名.class
  • 局部内部类:外部类$数字 内部类名.class

Java基础- - - - - - final(修饰方法)

  • 注意:使用final修饰一个private访问权限的方法,依然可以在其子类中定义与该方法具有相同方法名、相同形参列表、相同返回值类型的方法

Java基础- - - - - - abstract(注意)

用来abstract修饰:属性、构造器等结构

  • abstract不能用来修饰属性、构造器、私方法、静态方法、final的方法、final的类

Java基础- - - - - - 继承(子类调用构造器)

  • (1)如果子类构造器中,没有写super()或super(实参列表)语句,那么默认就是调用父类“无参构造”
  • (2)子类的构造器中,也可以手动调用父类的构造器,super()或super(实参列表)
  • (3)当父类没有无参构造时,子类的构造中必须手动调用父类的有参构造super(实参列表)
  • (4)super()或super(实参列表)它必须在子类构造器的首行

21.2.17

JavaDug- - - - - - Exception in thread “main” java.lang.Error: Unresolved compilation problem

  • 错误的原因是因为代码中没有指定package

JavaDug- - - - - - NoClassDefFoundError原因

NoClassDefFoundError和ClassNotFoundException

在java开发的过程经常会遇到这两个异常并且时常会产生混淆,为了便于区别,特作如下总结:

  • 相似点
    NoClassDefFoundError和ClassNotFoundException异常出现原因都是加载不到类导致,但是两者确有本质的区别。
  • 不同点
    ClassNotfoundException是在编译过程中JVM加载不到类或者找不到类引起
    NoClassDefError是在运行时JVM加载不到类或者找不到类引起

NoClassDefFoundError错误发生原因

NoClassDefFoundError错误发生原因与Java虚拟机的工作原理相关,下面简单介绍一下JVM的类加载机制,其中类加载器的三个机制为委托、单一性、可见性。

  • 委托:指加载一个类的请求交给父类加载器,若父类加载器不可以找到或者加载到,再加载这个类;
  • 单一性:指子类加载器不会再次加载父类加载器已经加载过的类 ;
  • 可见性:子类加载器可以看见父类加载器加载的所有类,而父类加载器不可以看到子类加载器加载的类
    JVM的委托机制决定了类加载器只加载一次,子类加载器不会再加载父类加载器已经加载过的类,因此在一些特定条件下就会出现编译时可以加载到类,运行时不可以加载到类,这时候就会出现java.lang.NoClassDefFoundError异常

Java基础- - - - - - 多线程(Thread的setName()方法使用注意)

  • 创建线程的时候设置名字
    在这里插入图片描述
  • 注意:
    在这里插入图片描述

Java基础- - - - - - 多线程(Thread的yield()方法使用注意)

  • JDK中注释,向调度程序暗示(hint)当前线程愿意让出CPU,调度程序可以忽略此暗示。也就是说当前线程可能根本就没有让出CPU,线程一直在运行。
  • 注意:测试程序电脑是否是多核CPU也会影响结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值