java学习:面向对象(下)---类和对象day06

177 阅读13分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第十五天,点击查看活动详情

其他

Java Bean

image.png

image.png

image.png

MVC设计模式

image.png

image.png

package import 关键字

image.png 注意:在同一个包里的两个类之间无需导入

image.png

image.png

Object类的使用

image.png

image.png

image.png

equals(重点)

经典面试题

image.png ==符号判断时,左右两边的数据类型应该一致

image.png 基本数据类型

image.png 引用数据类型 image.png

image.png

image.png

手动实现equals的重写

image.png

image.png

image.png

image.png

总结

image.png

toString()方法

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

单元测试

www.bilibili.com/video/BV1Qb…

image.png

image.png

image.png

开发中 直接在测试代码里写@test 按提示做即可

包装类

image.png

image.png

基本数据类型与包装类的相互转化

//基本数据类型 --->包装类:自动装箱或调用包装类的构造器
	@Test
	public void test1(){
		//写法1 自动装箱(推荐)
		Integer num11 =1;
		system.out.println(num11.toString()) //1
		
		
		//写法2(过时 调用包装类的构造器)
		int num1 = 10;		
		Integer in1 = new Integer(num1); //in1是对象
		
		
		//写法2的扩展
		Integer in2 = new Integer("123");  //也可以传String类型的参数进去  但是只能是数 
		//Integer in2 = new Integer("123asd"); //无法将这种字符串转换成包装类 //报异常
			
		
		Float f1 = new Float(12.3f);
		Float f2 = new Float("12.3");  //直接传了字符串  
		System.out.println(f1);
		System.out.println(f2);
		
		Boolean b1 = new Boolean(true);
		Boolean b2 = new Boolean("TrUe");
		System.out.println(b2);
		Boolean b3 = new Boolean("true123");
		System.out.println(b3);//false
		
		
		Order order = new Order();
		System.out.println(order.isMale);//false
		System.out.println(order.isFemale);//null  注意 这里默认值不再是false  因为Boolean是包装类
	}
	
}

class Order{
	
	boolean isMale;
	Boolean isFemale;  //Boolean是包装类
}



//包装类--->基本数据类型:调用包装类Xxx的xxxValue()
	//方便加减乘除
	@Test
	public void test2(){
		Integer in1 = new Integer(12);
		
		int i1 = in1.intValue(); //调用Integer的方法
		System.out.println(i1 + 1);
		
		
		Float f1 = new Float(12.3);
		float f2 = f1.floatValue(); //f2 就是一个基本数据类型了
		System.out.println(f2 + 1);
	}
自动装箱与拆箱


/*
	 * JDK 5.0 新特性:自动装箱 与自动拆箱
	 */
	@Test
	public void test3(){
			 
		
		//自动装箱:基本数据类型 --->包装类
		int num2 = 10;
		Integer in1 = num2;//自动装箱(替代了构造器的写法)
		
		boolean b1 = true;
		Boolean b2 = b1;//自动装箱
		
		//自动拆箱:包装类--->基本数据类型
				
		int num3 = in1;//自动拆箱  把包装类直接赋给基本数据类型
		
	}
	
	
//自动装箱的利用

package com.atguigu.exe;

import org.junit.Test;



public class UnitTest {  //测试类
	
	//基本数据类型转换成包装类
	@Test
	public void WrapperTest(){ //测试方法
		int num1 = 10;
		method(num1);  //10
	}
	
	 
	public void method(Object obj){
		System.out.println(obj);
	}

}

基本数据类型、包装类<--->String类型的相互转化

	//基本数据类型、包装类--->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 = "true1";  不符合true的都返回true
		boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);  //false  
	}
包装类面试题

image.png

第一题:1.0

解析: 三元运算符的两个表达式要类型统一 此处伴随着一个自动类型提升

第二题: 1

image.png 解析

image.png

static关键字

static修饰属性

image.png

image.png

image.png

image.png

image.png

image.png

类变量VS实例变量的内存解析

image.png

image.png

static修饰方法

image.png

image.png

image.png

设计模式与单例设计模式

image.png 23种设计模式

image.png

image.png

单例的饿汉式实现



package com.atguigu.exe;



public class Bank {
	public static void main(String[] args) {
		BankBank b1=BankBank.getInstance();
		BankBank b2=BankBank.getInstance();
		System.out.println(b1==b2); //true
	}
	
	
}
class BankBank{

	//1私有化构造器
	private BankBank(){
		
	}
	
	//2内部创建类的对象 必须是静态的
	private static BankBank instance=new BankBank();
	
	//3提供get方法 必须是静态的
	public static BankBank getInstance(){
		return instance;
	}

	
}

单例的懒汉式实现



package com.atguigu.exe;



public class Bank {
	public static void main(String[] args) {
			
		Book bb1 = Book.getInstance();
		Book bb2 = Book.getInstance();
		System.out.println(bb1==bb2); //true
		
	}
	
	
}

class Book{
	//私有化构造器
	private Book(){
		
	}
	//声明实例,没有初始化 必须是static
	private static Book instance=null;
	
	//提供实例的get方法  必须是static
	public static Book getInstance(){
		if(instance==null){
			return instance=new Book();
		}
		return instance;
	}
	
}

image.png

image.png

main方法

静态方法只能调静态的属性或方法

image.png

此时show( )方法是静态的 不需要new image.png

此时show( )方法是非静态的 需要new image.png

main方法的使用说明 image.png

image.png

image.png

final关键字

image.png


package com.atguigu.java3;
/*
 * final:最终的
 * 
 * 1. final可以用来修饰的结构:类、方法、变量
 * 
 * 2. final 用来修饰一个类:此类不能被其他类所继承。
 *          比如:String类、System类、StringBuffer类
 * 
 * 3. final 用来修饰方法:表明此方法不可以被重写
 * 			比如:Object类中getClass();
 * 
 * 4. final 用来修饰变量:此时的"变量"就称为是一个常量
 * 	    4.1 final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
 * 		4.2 final修饰局部变量:
 *           尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值
 *           以后,就只能在方法体内使用此形参,但不能进行重新赋值。
 *           
 *  static final 用来修饰属性:全局常量
                 (用来修饰方法:)
 */
public class FinalTest {
	
	final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
//	final int DOWN;
	
	{
		LEFT = 1;
	}
	
	public FinalTest(){
		RIGHT = 2;
	}
	
	public FinalTest(int n){
		RIGHT = n;
	}
	
//	public void setDown(int down){
//		this.DOWN = down;
//	}
	
	
	public void doWidth(){
//		width = 20;
	}
	
	
	public void show(){
		final int NUM = 10;//常量
//		NUM += 20;
	}
	
	public void show(final int num){
//		num = 20;//编译不通过
		System.out.println(num);
	}
	
	
	public static void main(String[] args) {
		
		int num = 10;
		
		num = num + 5;
		
		FinalTest test = new FinalTest();
//		test.setDown(3);
		
		test.show(10);
	}
}


final class FinalA{
	
}

//class B extends FinalA{
//	
//}

//class C extends String{
//	
//}

class AA{
	public final void show(){
		
	}
}

class BB extends AA{
	
//	public void show(){
//		
//	}
}

练习题

image.png

抽象类和抽象方法

image.png

package com.atguigu.java;
/*
 * abstract关键字的使用
 * 1.abstract:抽象的
 * 2.abstract可以用来修饰的结构:类、方法
 * 
 * 3. abstract修饰类:抽象类
 * 		> 此类不能实例化
 *      > 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
 *      > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
 * 
 * 
 * 4. abstract修饰方法:抽象方法
 * 		> 抽象方法只有方法的声明,没有方法体
 * 		> 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
 *      > 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
 *        若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
 */
public class AbstractTest {
	public static void main(String[] args) {
		
		//一旦Person类抽象了,就不可实例化
//		Person p1 = new Person();
//		p1.eat();
		
	}
}

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 void eat(){
//		
//	}
	//抽象方法
	public abstract void eat();
	
	public void walk(){
		System.out.println("人走路");
	}
	
	
}


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("学生应该呼吸新鲜的没有雾霾的空气");
	}
}

image.png

image.png

抽象类的匿名子类

意义:不用再创建子类

//这段代码就不用再写
class Worker extends Person{

	@Override
	public void eat() {
	}

	@Override
	public void breath() {
	}
	
}




package com.atguigu.java;
/*
 * 抽象类的匿名子类
 * 
 */
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){
		
	}
}

//注释:Person类是一个抽象类
class Worker extends Person{

	@Override
	public void eat() {
	}

	@Override
	public void breath() {
	}
	
}

模板方法设计模式---抽象类的应用

image.png

image.png

image.png

image.png

image.png

//应用


package com.atguigu.java;
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {

	public static void main(String[] args) {
		BankTemplateMethod btm = new DrawMoney();
		btm.process();

		BankTemplateMethod btm2 = new ManageMoney();
		btm2.process();
	}
}
abstract class BankTemplateMethod {
	// 具体方法
	public void takeNumber() {
		System.out.println("取号排队");
	}

	public abstract void transact(); // 办理具体的业务 //钩子方法

	public void evaluate() {
		System.out.println("反馈评分");
	}

	// 模板方法,把基本操作组合到一起,子类一般不能重写
	public final void process() {
		this.takeNumber();

		this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码

		this.evaluate();
	}
}

class DrawMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("我要取款!!!");
	}
}

class ManageMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("我要理财!我这里有2000万美元!!");
	}
}

练习

image.png

image.png

接口

image.png

image.png

让类实现接口


package com.atguigu.java1;
/*
 * 接口的使用
 * 1.接口使用interface来定义
 * 2.Java中,接口和类是并列的两个结构
 * 3.如何定义接口:定义接口中的成员
 * 		
 * 		3.1 JDK7及以前:只能定义全局常量和抽象方法
 * 			>全局常量:public static final的.但是书写时,可以省略不写
 * 			>抽象方法:public abstract的
 * 			
 * 		3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
 * 
 * 4. 接口中不能定义构造器的!意味着接口不可以实例化
 * 
 * 5. Java开发中,接口通过让类去实现(implements)的方式来使用.
 *    如果实现类覆盖(实现)了接口中的所有抽象方法,则此实现类就可以实例化
 *    如果实现类没有覆盖(实现)接口中所有的抽象方法,则此实现类仍为一个抽象类
 *    
 * 6. Java类可以实现多个接口   --->弥补了Java单继承性的局限性
 *   格式:class AA extends BB implements CC,DD,EE
 *   
 * 7. 接口与接口之间可以继承,而且可以多继承
 * 
 * *******************************
 * 8. 接口的具体使用,体现多态性
 * 9. 接口,实际上可以看做是一种规范
 * 
 * 面试题:抽象类与接口有哪些异同?
 相同:都不能实例化,都有抽象方法,都需要有实现类来实现,自身无法实现方法
 不同:
 1抽象类可以存在普通方法,接口中只能存在public abstract方法.
 2抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的(全局常量)
 3抽象类只能继承一个,接口可以实现多个.
 4关键字不同:abstract和interface
 5实现方式不同:抽象类用extends,接口用implements来实现
 抽象类描述的是事物的抽象特性,接口描述的是
 * 
 */
public class InterfaceTest {
	public static void main(String[] args) {
		System.out.println(Flyable.MAX_SPEED);
		System.out.println(Flyable.MIN_SPEED);
//		Flyable.MIN_SPEED = 2;
		
		Plane plane = new Plane();
		plane.fly();
	}
}


interface Flyable{
	
	//全局常量
	public static final int MAX_SPEED = 7900;//第一宇宙速度
	int MIN_SPEED = 1;//省略了public static final
	
	//抽象方法
	public abstract void fly();
	//省略了public abstract
	void stop();
	
	
	//Interfaces cannot have constructors
//	public Flyable(){
//		
//	}
}

interface Attackable{
	
	void attack();
	
}

class Plane implements Flyable{

	@Override
	public void fly() {
		System.out.println("通过引擎起飞");
	}

	@Override
	public void stop() {
		System.out.println("驾驶员减速停止");
	}
	
}

abstract class Kite implements Flyable{

	@Override
	public void fly() {
		
	}
	
}

class Bullet extends Object implements Flyable,Attackable,CC{

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void method1() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void method2() {
		// TODO Auto-generated method stub
		
	}
	
}
//************************************

interface AA{
	void method1();
}
interface BB{
	
	void method2();
}

interface CC extends AA,BB{
	
}

接口应用和创建接口匿名实现类的对象

image.png

image.png


package com.atguigu.java1;
/*
 * 接口的使用
 * 1.接口使用上也满足多态性
 * 2.接口,实际上就是定义了一种规范(本例中,谁要是想和电脑传输数据,都要先实现一下USB接口中定义的规范,也就是实现接口))
 * 3.开发中,体会面向接口编程!
 * 
 */
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("打印机结束工作");
	}
	
}


接口应用--代理模式

image.png

image.png 此处举例是静态代理

举例一


package com.atguigu.java1;
/*
 * 接口的应用:代理模式
 * 
 */
public class NetWorkTest {
	public static void main(String[] args) {
		Server server = new Server();
//		server.browse();
		ProxyServer proxyServer = new ProxyServer(server);
		
		proxyServer.browse();
		
	}
}

interface NetWork{
	
	public void browse();
	
}

//被代理类
class Server implements NetWork{

	@Override
	public void browse() {
		System.out.println("真实的服务器访问网络");
	}

}
//代理类
class ProxyServer implements NetWork{
	
	private NetWork work;
	
	public ProxyServer(NetWork work){
		this.work = work;
	}
	

	public void check(){
		System.out.println("联网之前的检查工作");
	}
	
	@Override
	public void browse() {
		check();
		
		work.browse();
		
	}
	
}

举例二

package com.atguigu.java1;


public class StaticProxyTest {

	public static void main(String[] args) {
		Proxy s = new Proxy(new RealStar());
		s.confer();
		s.signContract();
		s.bookTicket();
		s.sing();
		s.collectMoney();
	}
}

interface Star {
	void confer();// 面谈

	void signContract();// 签合同

	void bookTicket();// 订票

	void sing();// 唱歌

	void collectMoney();// 收钱
}
//被代理类
class RealStar implements Star {

	public void confer() {
	}

	public void signContract() {
	}

	public void bookTicket() {
	}

	public void sing() {
		System.out.println("明星:歌唱~~~");
	}

	public void collectMoney() {
	}
}

//代理类
class Proxy implements Star {
	private Star real;

	public Proxy(Star real) {
		this.real = real;
	}

	public void confer() {
		System.out.println("经纪人面谈");
	}

	public void signContract() {
		System.out.println("经纪人签合同");
	}

	public void bookTicket() {
		System.out.println("经纪人订票");
	}

	public void sing() {
		real.sing();
	}

	public void collectMoney() {
		System.out.println("经纪人收钱");
	}
}

接口面试题

image.png

注释掉的代码 编译不通过 因为父类和接口中的x变量同名了

image.png

image.png

java8中的接口新特性

image.png

image.png

image.png

image.png

image.png

练习

image.png

image.png

image.png

image.png

类的成员五 内部类

image.png


package com.atguigu.java2;
/*
 * 类的内部成员之五:内部类
 * 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
 * 
 * 2.内部类的分类:成员内部类(静态、非静态)  vs 局部内部类(方法内、代码块内、构造器内)
 * 
 * 3.成员内部类:
 * 		一方面,作为外部类的成员:
 * 			>调用外部类的结构
 * 			>可以被static修饰
 * 			>可以被4种不同的权限修饰
 * 
 * 		另一方面,作为一个类:
 * 			> 类内可以定义属性、方法、构造器等
 * 			> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
 * 			> 可以被abstract修饰
 * 
 * 
 * 4.关注如下的3个问题
 *   4.1 如何实例化成员内部类的对象
 *   4.2 如何在成员内部类中区分调用外部类的结构
 *   4.3 开发中局部内部类的使用  见《InnerClassTest1.java》
 * 
 */
public class InnerClassTest {
	public static void main(String[] args) {
		
		//创建Dog实例(静态的成员内部类):
		Person.Dog dog = new Person.Dog();
		dog.show();
		//创建Bird实例(非静态的成员内部类):
//		Person.Bird bird = new Person.Bird();//错误的
		Person p = new Person();
		Person.Bird bird = p.new Bird();
		bird.sing();
		
		System.out.println();
		
		bird.display("黄鹂");
		
	}
}


class Person{
	
	String name = "小明";
	int age;
	
	public void eat(){
		System.out.println("人:吃饭");
	}
	
	
	//静态成员内部类
	static class Dog{
		String name;
		int age;
		
		public void show(){
			System.out.println("卡拉是条狗");
//			eat();
		}
		
	}
	//非静态成员内部类
	class Bird{
		String name = "杜鹃";
		
		public Bird(){
			
		}
		
		public void sing(){
			System.out.println("我是一只小小鸟");
			Person.this.eat();//调用外部类的非静态属性
			eat();
			System.out.println(age);
		}
		
		public void display(String name){
			System.out.println(name);//方法的形参
			System.out.println(this.name);//内部类的属性
			System.out.println(Person.this.name);//外部类的属性
		}
	}
	
	
	public void method(){
		//局部内部类
		class AA{
			
		}
	}
	
	{
		//局部内部类
		class BB{
			
		}
	}
	
	public Person(){
		//局部内部类
		class CC{
			
		}
	}
	
	
	
}