Java基础--- 转型 Casting

基础类型转型

自动类型转换

  • 低类型可被自动转换成高类型
  • 不能对boolean类型进行类型转换
-----------------------------------byte, short, char --> int --> long --> float --> double

强制类型转换

  • 条件是转换的数据类型必须是兼容的 (比如int转换为byte, 则int的大小必须在 -127 - 127 之间)
  • 格式:(type)value type是要强制类型转换后的数据类型
int i = 120;
byte b = (byte)i;
System.out.println(b);

基础类型转换为String

使用基础类型对应包装类的parse方法, 包括:

Byte:

static byte	parseByte(String s): Parses the string argument as a signed decimal byte.
static byte	parseByte(String s, int radix): Parses the string argument as a signed byte in the radix specified by the second argument.

Short:

static short parseShort(String s): Parses the string argument as a signed decimal short.
static short parseShort(String s, int radix): Parses the string argument as a signed short in the radix specified by the second argument.

Integer:

static int	parseInt(String s): Parses the string argument as a signed decimal integer.
static int	parseInt(String s, int radix): Parses the string argument as a signed integer in the radix specified by the second argument.
static int	parseUnsignedInt(String s): Parses the string argument as an unsigned decimal integer.
static int	parseUnsignedInt(String s, int radix): Parses the string argument as an unsigned integer in the radix specified by the second argument.

Long

static long parseLong(String s)  
static long parseLong(String s, int radix)                 

Float

static float parseFloat(String s): Returns a new float initialized to the value represented by the specified String, as performed by the valueOf method of class Float.

Double

static double parseDouble(String s): Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.

引用类型转型

Upcastig and Implicitly Casting

  • Upcasting: 父类的引用指向子类的对象实例(子类对象实例的声明类型为父类,向上转换了), 下面都是upcasting
  • Object o1 = new subclassOfObject()
  • o1 = s1
  • Upcasting的变量的声明类型是父类,实际类型是子类,引用指向的是一个子类实例
  • Upcasting的变量只能使用父类的方法,而不能使用子类独有的方法
  • Implicitly casting: 编译器可自动完成upcasting

Example 1

public class Fruit {
	public void type() {
		System.out.println("This is fruit");
	}
}
public class Apple extends Fruit {
	public void type() {
		System.out.println("This is Apple");
	}
	
	public void appleJuice() {
		System.out.println("Apple Juice");
	}
}
public class Peach extends Fruit{
	public void type() {
		System.out.println("This is peach");
	}
	
	public void peachJuice() {
		System.out.println("Peach Juice");
	}
	
	public static void displayType(Fruit o) {	
		if(o instanceof Peach) {
			((Peach) o).peachJuice();
		}
		else if(o instanceof Apple) {
			((Apple) o).appleJuice();
		}
	}
	
	public static void main(String[] args) {
		Fruit f1 = new Peach();
		Fruit p1 = new Apple();
		o1.type();
		o2.type();
		//o1.peachJuice; Error
		//o2.appleJuice; Error
	}

}
  • O1 和 O2的声明类型为Fruit,但是实际类型为Peach和Apple
  • 此时O1,O2只能使用父类的方法,而不能使用子类独有的方法(动态绑定),所以25,26行会报错

Example 2

public class Fruit {
	public void type() {
		System.out.println("This is fruit");
	}
}
public class Apple extends Fruit {
	public void type() {
		System.out.println("This is Apple");
	}
	
	public void appleJuice() {
		System.out.println("Apple Juice");
	}
}
public class Peach extends Fruit{
	public void type() {
		System.out.println("This is peach");
	}
	
	public void peachJuice() {
		System.out.println("Peach Juice");
	}
	
	public static void displayType(Fruit o) {	
		if(o instanceof Peach) {
			((Peach) o).peachJuice();
		}
		else if(o instanceof Apple) {
			((Apple) o).appleJuice();
		}
	}
	
	public static void main(String[] args) {
		Fruit f1 = new Fruit();
		Fruit p1 = new Peach();
		
		//check memory address:
		System.out.println("before casting: f1 address is " + f1.toString());
		System.out.println("before casting: p1 address is " + p1.toString());
		
		
		f1 = p1; //upcasting
		//after casting the decalred type of f1 is Fruit, and the actual type is peach
	
		
		//check memory address:
		System.out.println("---------------------------------------------");
		System.out.println("after casting: f1 address is " + f1.toString());
		System.out.println("after casting: p1 address is " + p1.toString());
		
		
		System.out.println("---------------------------------------------");
		System.out.println("check what methods that f1 can use: ");
		f1.type(); 
		//f1.peachJuice(); Error
		
		System.out.println("check what methods that p1 can use: ");
		p1.type();
	}

}

output:
before casting: f1 address is upcasting.Fruit@3fee733d
before casting: p1 address is upcasting.Peach@5acf9800
---------------------------------------------
after casting: f1 address is upcasting.Peach@5acf9800
after casting: p1 address is upcasting.Peach@5acf9800
---------------------------------------------
check what methods that f1 can use: 
This is peach
check what methods that p1 can use: 
This is peach
  • 在upcasting之前,f1,p1的地址不一样
  • 在upcasting之后,f1的地址更改为p1的地址,并且类型改为peach
  • 在Upcasting之后,虽然f1的地址为p1的地址,并且类型也是peach,但是还是不能使用p1的独有方法
  • 这是因为f1的声明类型依然是fruit,实际类型是peach,需要遵守动态绑定,所以p1的独有方法不能使用。

Downcasting and Explicitly Casting

  • Downcasting: 将子类的引用指向父类的对象实例
  • 需要使用 (subclass type) superclass variable格式完成casting ---- Explicitly Casting
  • subclass s = (subclass) Object
  • downcast的类型要遵循object的实际类型 (Example1)
  • 所以在downcasting之前, 必须判断被转型的类是子类的instance(, 用instance of关键字
  • Instanceof : 只知道一个变量是superclass的instance,但是不确定是否是subclass的instance,此时需要用instanceof判断

Example 1:

Car audi = new Audi();
Audi a = (Audi)myCar;
a.AudiPrice();
  • Car的实际类型也是Car,所以不能被downcasting
  • 所以不能强行将一个子类的引用指向父类的对象,要先判断类型

Upcasting和downcasting的实际作用 ----- 实现多态

package downcasting;

public class Audi extends Car {
	
	public void whatObject() {
		System.out.println("This is the car object from Audi");
	}
	
	public void AudiPrice() {
		System.out.println("The price for Audi is 20000");
	}
	
	//编译器进行了upcasting(implicitly)在display方法里,变量myCar的声明类型是Car,但实际类型是Audi或者Benz
	public static void display(Car myCar) {
		 //但是调用实际类型的方法
		 myCar.whatObject();
		 
		 if (myCar instanceof Benz) {
		 	 //进行downcasting
			 Benz b = (Benz)myCar;
			 b.BenzPrice();
		 }
		 else if (myCar instanceof Audi) {
			 //进行downcasting
			 Audi a = (Audi)myCar;
			 a.AudiPrice();
		 }
	}
	
	public static void main(String[] args) {
		//声明一个 audi,benz类型的变量
		Audi audi = new Audi();
		Benz benz = new Benz();

		display(audi);
		display(benz);
	}
}

output:
This is the car object from Audi
The price for Audi is 20000
This is the car object from Benz
The price for Benz is 10000
  • 这样可以达到节省代码量,generic programming的目的,是多态的表现形式之一
    如果没有upcasting,则需要写两遍display方法,如下:
package downcasting;

public class Audi extends Car {
	
	public void whatObject() {
		System.out.println("This is the car object from Audi");
	}
	
	public void AudiPrice() {
		System.out.println("The price for Audi is 20000");
	}
	
	public static void display(Audi myCar) {
		 myCar.whatObject();
		 myCar.AudiPrice();
	}
	
	public static void display(Benz myCar) {
		 myCar.whatObject();
		 myCar.BenzPrice();
	}
	
	public static void main(String[] args) {
		Audi audi = new Audi();
		Benz benz = new Benz();

		display(audi);
		display(benz);
	}
}

Notes

对引用类型的Casting不会创建一个新的变量
在这里插入图片描述

java根据变量的声明类型判断类型是否一致

  • 编译器没有报错,可以正常运行
  • 因为myAudi和car的声明类型都是Car,所以不会报错
  • 赋值完成后,myAudi的实际类型也变成car,彻底和子类失去联系
public static void main(String [] args) {
      Car myAudi = new Audi();
      Car car = new Car();
      myAudi.whatObject();
      myAudi = car;
      myAudi.whatObject();
}

output:
This is the car object from Audi
This is car object
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值