疯狂Java讲义_Chapter06面向对象(下)(未更新完,有时间再更)

1.包装类

  • 包装类的产生原因是针对8种数值型变量进行封装处理,为了解决8种基本数据类型不能被当做Object类型处理;
  • 包装类:
Byte
Short
Integer
Long
Character
Float
Double
Boolean
  • JDK 1.6提供了自动装箱和自动拆箱功能
  1. 自动装箱:可以把一个基本变量直接赋值给包装类或者Object类型;
  2. 自动拆箱:直接把包装类直接赋值给基本类型变量;

public class AutoBoxingUnboxing
{
	public static void main(String[] args)
	{
		//包装类intObj
		Integer inObj = 5;
		// Object对象
		Object boolObj = true;
		// 自动拆箱ֱ
		int it = inObj;
		if (boolObj instanceof Boolean)
		{
			// 将Obj对象向下转型,再拆箱;
			boolean b = (Boolean) boolObj;
			System.out.println(b);
		}
	}
}
  •  通过自动装箱和自动拆箱,基本类型可以被近似当成对象使用;
  • 基本类型和字符串之间的转换方法:

public class Primitive2String
{
	public static void main(String[] args)
	{
		var intStr = "123";
		// 2种转换方法:
		var it1 = Integer.parseInt(intStr); //除了Character以外都有
		var it2 = Integer.valueOf(intStr);
		System.out.println(it2);
		var floatStr = "4.56";
		
		var ft1 = Float.parseFloat(floatStr);
		var ft2 = Float.valueOf(floatStr);
		System.out.println(ft2);
		
		var ftStr = String.valueOf(2.345f);
		System.out.println(ftStr);
		
		var dbStr = String.valueOf(3.344);
		System.out.println(dbStr);
		
		var boolStr = String.valueOf(true);
		System.out.println(boolStr.toUpperCase());


// 向上转型直接转换为String
var itStr = 5 + "";
	}
}
  • 包装类的无符号运算:

public class UnsignedTest
{
	public static void main(String[] args)
	{
		byte b = -3;
		// 将b转换为无符号整数:
		System.out.println(Byte.toUnsignedInt(b)); // 253
		// ָ指定使用16进制解析无符号整数
		var val = Integer.parseUnsignedInt("ab", 16);
		System.out.println(val); // 输出171
		// 将-12转换为无符号int型,然后转换为16进制表述的字符串
		System.out.println(Integer.toUnsignedString(-12, 16)); // fffffff4
		// 将两个数转换为无符号整数后删除
		System.out.println(Integer.divideUnsigned(-2, 3));
		// 将两个数转换为无符号整数后相除求余;
		System.out.println(Integer.remainderUnsigned(-2, 7));
	}
}

 

2.处理对象

1.打印对象和toString方法

  • 当使用控制台打印对象的时候,打印出的是对象的toString方法的返回值;
  • toString方法是Object类的固有方法,所有的Java类都有这个方法;
  • 类的toString方法返回该对象的“类名+@+hashcode”;
  • 自定义实现toString 方法

class Apple
{
	private String color;
	private double weight;
	public Apple(){	}
	
	public Apple(String color, double weight)
	{
		this.color = color;
		this.weight = weight;
	}
	
	public void setColor(String color)
	{
		this.color = color;
	}
	public String getColor()
	{
		return this.color;
	}
	
	public void setWeight(double weight)
	{
		this.weight = weight;
	}
	public double getWeight()
	{
		return this.weight;
	}
	
	public String toString()
	{
		return  color + weight;
	}
}
public class ToStringTest
{
	public static void main(String[] args)
	{
		var a = new Apple("苹果", 5.68);
		
		System.out.println(a);
	}
}

 

2.==和equal方法

  • 当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型,则只要两个变量值相等,为true;但是对于两个引用类型来说,只有他们指向的对象为同一个对象时,==判断才会返回true;
  • equal方法和==方法没有区别,但是程序员可以通过重写equal方法来改变等价判断方法;String类就重写了equal方法,只要字符串内容一致,就返回true;

public class EqualTest
{
	public static void main(String[] args)
	{
		var it = 65;
		var fl = 65.0f;
		// 输出true
		System.out.println(it == fl);
		var ch = 'A';
		// 输出true
		System.out.println(it == ch);
		var str1 = new String("hello");
		var str2 = new String("hello");
		// 输出false
		System.out.println(str1 == str2);
		// 输出true
		System.out.println(str1.equals(str2));
	}
}
  • 通常,重写equal方法要满足的条件:
  1. 自反性:对任意x,x.equal(x)一定是true;
  2. 对称性:对任意x和y,如果y.equal(x)返回true,那么x.equal(y)也返回true;
  3. 传递性:对x,y,z,如果x.equal(y) is true, y.equal(z) is true, then x.qual(z) is true;
  4. 一致性:对于x和y,如果对象中用于比较的信息没有变,那么无论调用x.equal(y)多少次,返回的结果都应该保持一致;
  5. 对任何不是null的x, x.equal(null)一定返回false; 

3.类成员

  • 使用static修饰的成员就是类成员,static可以修饰方法、变量和代码块,不能修饰构造方法;
  • static修饰的成员只能通过类名调用,且在类定义的时候就会被分配内存;
  • 如果一个类只能创建一个对象,称为单例成员,单例成员的构造详见设计模式中的单例设计模式:

4.final修饰符

  • final可以用于修饰类,变量和方法;和C#中的sealed一样,final修饰的东西一旦获得初始值就不可改变;
  • final定义的成员必须由程序员显示赋值,务必定义final的时候就直接赋值;
  • final修饰基本类型时,值不能改变,但是final修饰引用类型时,仅仅是引用类型的地址值不能改变,内容可以改变;
  • final修饰符的重要应用就是宏变量,可以在编译的时候直接确定下来,不用分配指向内存;
  • final方法不可被重写;如果不希望父类方法被重写,可以使用final;
  • final修饰的类不可以有子类;

5.抽象类

  • 抽象类和抽象方法的定义:
  1. 抽象方法和抽象类必须使用abstract定义;
  2. 有抽象方法的类只能被定义为抽象类,抽象类里可以没有抽象方法;
  3. 抽象方法不能有方法体;
  4. 抽象类不能实例化;
  5. 抽象类可以包含成员,方法,构造体,初始化块、内部类;
  • 定义一个抽象类:

public abstract class Shape
{
	{
		System.out.println("ִ执行Shape的初始化块");
	}
	private String color;
	// 定义一个抽象方法
	public abstract double calPerimeter();
	public abstract String getType();
	// 构造方法(只能子类调用)
	public Shape(){}
	public Shape(String color)
	{
		System.out.println("ִ形状是");
		this.color = color;
	}
	// 常规方法
	public void setColor(String color)
	{
		this.color = color;
	}
	public String getColor()
	{
		return this.color;
	}
}
  • 继承实现抽象类

public class Triangle extends Shape
{
	private double a;
	private double b;
	private double c;
	public Triangle(String color, double a, double b, double c)
	{
		super(color);   //调用抽象类的构造方法
		this.setSides(a, b, c);
	}
	//给三角形赋值三边;
	public void setSides(double a, double b, double c)
	{
		if (a >= b + c || b >= a + c || c >= a + b)
		{
			System.out.println("这不是三角形");
			return;
		}
		this.a = a;
		this.b = b;
		this.c = c;
	}
	// 计算周长
	public double calPerimeter()
	{
		return a + b + c;
	}
	// 返回类型
	public String getType()
	{
		return "三角形";
	}
}

6.Java9改进的接口

1.接口的概念和定义

  • 接口是一种规范,接口定义了某一批类需要执行的规范,也就是规定类里必须出现的方法;
  • 定义一个接口:
[修饰符] interface 接口名 extends 父接口1,父接口2...
        {
            常量定义;
            抽象方法定义;
            内部类、接口、枚举;
            私有方法、默认方法...
        }
  • 修饰符可以是public或者省略;如果省略,只能在相同包下访问接口;
  •  一个接口可以有多个父接口,但是不能继承类;
  • 接口里的成员变量只能是静态常量(默认public final static);方法默认是公共抽象方法;

2.接口的继承

  • 子接口扩展父接口,会直接获得父接口中定义的所有常量和抽象方法;

interface InterfaceA
{
	int PROP_A = 5;
	void testA();
}
interface InterfaceB
{
	int PROP_B = 6;
	void testB();
}
interface InterfaceC extends InterfaceA, InterfaceB
{
	int PROP_C = 7;
	void testC();
}
public class InterfaceExtendsTest
{
	public static void main(String[] args)
	{
		System.out.println(InterfaceC.PROP_A);
		System.out.println(InterfaceC.PROP_B);
		System.out.println(InterfaceC.PROP_C);
	}
}

3.使用接口

  • 接口的主要用途:
  1. 定义变量,也可用于强制类型转换;
  2. 调用接口中定义的常量;
  3. 被其他类发现;模拟多继承;
  • 一个类可以实现多个接口;当类继承了接口的方法之后,它必须完全实现这个接口所定义的全部抽象方法,否则该类会成为抽象类;

4.接口和抽象类

  • 接口是最终件(不可轻易改变),抽象类是中间件(改动对系统影响不大);
  • 接口和抽象类的区别(201)

5.面向接口编程(详见各种设计模式)

7.内部类(205)

8.Lambda表达式(简化的匿名内部类)

  • lambda表达式可以简化创建匿名内部类对象:

public class CommandTest
{
	public static void main(String[] args)
	{
		var pa = new ProcessArray();
		int[] target = {3, -4, 6, 4};
		// 使用匿名内部类作为参数
		pa.process(target, new Command()
		{
			public void process(int element)
			{
				System.out.println("数组元素的平方是:" + element * element);
			}
		});
	}
}

public class CommandTest2
{
	public static void main(String[] args)
	{
		var pa = new ProcessArray();
		int[] array = {3, -4, 6, 4};
		// 用lambda表达式进行改写:
		pa.process(array, (int element)->{
				System.out.println("����Ԫ�ص�ƽ����:" + element * element);
			});
	}
}

  • lambda表达式的格式:
(形参列表)->{代码块}
只有一个形参可以省略();只有一条语句可以省略{}
lambda表达式会被当成任意类型的对象,取决于运行环境的需求;
  •  例子:
interface Eatable
{
	void taste();
}
interface Flyable
{
	void fly(String weather);
}
interface Addable
{
	int add(int a, int b);
}
public class LambdaQs
{
	// 调用该方法需要Eatable对象;
	public void eat(Eatable e)
	{
		System.out.println(e);
		e.taste();
	}
	// 调用该方法需要Flyable对象
	public void drive(Flyable f)
	{
		System.out.println("我正在驾驶" + f);
		f.fly("天气清凉");
	}
	// 调用该方法需要Addable对象
	public void test(Addable add)
	{
		System.out.println("5和3的和为" + add.add(5, 3));
	}
	public static void main(String[] args)
	{
		var lq = new LambdaQs();
		lq.eat(() -> System.out.println("味道不错"));    //实现了Eatable接口中的taste方法
		lq.drive(weather -> {
			System.out.println("今天的天气是" + weather);    //实现了fly方法
			System.out.println("ֱjdifjisjfisjdif");
		});
		// 代码块只有一条语句,即使该表达式需要返回值,也可以省略return关键字;
		lq.test((a, b) -> a + b);   
	}
}
  •  lambda表达式的类型是“函数式接口类型”,函数式接口类型代表只包含一个抽象方法的接口;注解:@functionalInterface;
  • lambda表达式的函数式接口;在lambada表达式中使用var;方法引用与构造器引用;lambda表达式与匿名内部类的区别;lambda表达式调用Arrays类方法;(226)

9.枚举类

 

10.垃圾回收

11.多版本Jar包

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值