47.父子类之间的转换
(1)子类转换成父类
子类可以自动转型成父类
如果子类对父类的方法有覆写,并且子类的实例赋值给父类的引用,通过这个引用来调用这个覆写的方法的时候,调用的是子类。
父类指向子类的实例的引用不能调用子类的特有的方法和属性。
如果父子类有同名的属性,那么父类指向子类的实例的引用调用这个属性的时候调用的还是父类的,不要和方法混淆。
class Dog{
String name;
int age=1;
public void sleep(){
System.out.println(name+"在午休");
public void speek(){
System.out.println(name+"汪汪汪");
class Erha extends Dog{
//创建一个父类中同样的属性初始化不一样的值
int age=5;
//创建一个子类中特有的属性
boolean isMarry;
//创建一个子类中特有的方法
public void eat(){
System.out.println(name+"在吃狗粮");
//重写父类中的方法
public void speek(){
System.out.println(name+"冲着你汪汪汪");
public class Test{
public static void main(String[] args){
//创建一个父类指向子类的实例,子类可以自动转换成父类
Dog d=new Erha();
//可以访问父类中的属性
d.name="大可爱";
//当父子属性相同时,子类转换成父类的引用调用的也是父类中的属性
System.out.println(d.name+d.age+"岁");//大可爱1岁
//d.isMarry=false;//无法访问子类中特有的属性
//可以访问父类中的方法
d.sleep();//大可爱在午休
//当子类中的方法重写父类中的方法时,子类转换成父类的引用调用的是子类中的方法
d.speek();//大可爱冲着你汪汪汪
//d.eat(); //无法访问子类中特有的方法,注意区分重写方法
}
(2)父类转换成子类
特点:
-
父类转换成子类不能自动完成。
-
父类转换成子类的前提是父类的真身是这个子类,转回子类后,就可以访问子类内部的方法和属性。
-
如果这个父类的真身是子类B,不能强制转换成子类A,只能转换成B。
-
抽象类作为父类同样符合上述理论
-
接口中也是完全符合上述理论,但是注意接口中没有属性。
class Dog1{
String name;
int age=1;
public void sleep(){
System.out.println(name+"在午休");
public void speek(){
System.out.println(name+"汪汪汪");
class Erha1 extends Dog1{
//创建一个父类中同样的属性初始化不一样的值
int age=5;
//创建一个子类中特有的属性
boolean isMarry;
//创建一个子类中特有的方法
public void eat(){
System.out.println(name+"在吃狗粮");
//重写父类中的方法
public void speek(){
System.out.println(name+"冲着你汪汪汪");
class Taidi extends Dog1{
public class Test1{
public static void main(String[] args){
//创建一个父类指向子类的实例,子类可以自动转换成父类
Dog1 d=new Erha1();
//Taidi t=(Erha1)d;// 不兼容的类型: Erha1无法转换为Taidi,转化成父类的子类不能转成其他子类
//有且仅有转化成父类的子类才可以再转换成子类
Erha1 e=(Erha1)d; //可以访问父子类中的属性,属性相同时,优先调用的是子类中的属性
e.name="大可爱";
e.isMarry=false;
System.out.println(e.name+e.age+"岁");//大可爱5岁
//可以访问父子类中的方法,当子类中的方法重写父类中的方法时,调用的是子类中的方法
e.sleep();//大可爱在午休
e.speek();//大可爱冲着你汪汪汪
e.eat(); //访问子类中特有的方法
}
48.多态
多态就是行为具有表现多种功能的能力。(方法相同,表现形式或者对象不同)
(1)继承多态 通过继承的方式来体现的多态。
继承多态,不仅仅是父类是抽象类,父类是普通类也是可以的。
多态的条件:子类对父类有方法重写;父类的引用指向子类的实例,调用覆写的这个方法的时候,调用是子类的方法。
//定义一个父类,抽象父类或者普通父类都可以
abstract class Dog2{
String name;
int age;
public abstract void eat();
public abstract void speek();
//定义一个子类继承父类
class Erha2 extends Dog2{
public void eat(){
System.out.println(name+"在吃狗粮");
public void speek(){
System.out.println(name+"冲着你汪汪汪");
//定义一个另一个子类继承父类
class Taidi1 extends Dog2{
public void eat(){
System.out.println(name+"在吃土");
public void speek(){
System.out.println(name+"冲着你爸爸汪汪汪");
//创建一个主人类
class Master{
//在主人类中创建一个方法写针对Dog2类为参数写故事
public void lead(Dog2 d){//注意:d instanceof Erha2判断父类的实际的真身是哪个子类的实例
if(d instanceof Erha2){
System.out.println("二哈开始虐主子了");
if(d instanceof Taidi1){
System.out.println("泰迪开始虐主子了");
d.eat();
d.speek();
System.out.println("主人扔掉了"+d.name);
public class Test2{
public static void main(String[] args){
//创建一个Erha2实例并命名
Erha2 e=new Erha2();
e.name="二哈";
//创建一个Taidi1实例并命名
Taidi1 t=new Taidi1();
t.name="泰迪";
//创建一个主人实例
Master m=new Master();
//调用方法,子类自动转换成父类并且实现方法的不同表现形式
m.lead(e);
m.lead(t);
}//注意:d instanceof Erha2判断父类的实际的真身是哪个子类的实例
(2)接口多态
//定义一个父类
interface Dog3{
public void eat();
public void speek();
//定义一个子类实现接口
class Erha3 implements Dog3{
String name;
public void eat(){
System.out.println(name+"在吃狗粮");
public void speek(){
System.out.println(name+"冲着你汪汪汪");
//定义一个另一个子类实现接口
class Taidi2 implements Dog3{
String name;
public void eat(){
System.out.println(name+"在吃土");
public void speek(){
System.out.println(name+"冲着你爸爸汪汪汪");
//创建一个主人类
class Master{
//在主人类中创建一个方法写针对Dog3类为参数写故事
public void lead(Dog3 d){
//注意:接口中没有属性的定义,针对接口的方法中不能出现没有定义的属性
if(d instanceof Erha3){
System.out.println("二哈开始虐主子了");
if(d instanceof Taidi2){
System.out.println("泰迪开始虐主子了");
d.eat();
d.speek();
public class Test3{
public static void main(String[] args){
//创建一个Erha2实例并命名
Erha3 e=new Erha3();
e.name="二哈";
//创建一个Taidi1实例并命名
Taidi2 t=new Taidi2();
t.name="泰迪";
//创建一个主人实例
Master m=new Master();
//调用方法,子类自动转换成父类并且实现方法的不同表现形式
m.lead(e);
m.lead(t);
}
49.包
包:就是文件夹
作用:对类做分类管理,可以区分同名不同包的类。
语法: package 包名(不同级别用“.”来分隔);,如 package com.rl;, 位置放置文件的有效代码第一行(注释不算), 包的名字一定是英文的小写。
如何编译:
Javac –d . 源文件(比如:D:\source_code\2019-05-08>javac -d . Bag.java 编译过程中自动创建名为com的文件夹,com中又创建名为tx文件夹,里面是编译之后的Bag.class文件)
运行要带着包:
Java 包名.源文件名(比如:D:\source_code\2019-05-08>java com.tx.Bag)
//package 包名(不同级别用“.”来分隔);
package com.tx;
public class Bag{
public static void printArr(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+"\t");
public static void main(String[] args){
printArr(new int[]{1,2,3,4,5,6});
}
(1)如果两个类在相同的包内,可以不用引入类就能直接用
(2)如果两个类在不同的包内,必须要引入类才能使用。前提被引入的类是public的
引入类的语法 在包的下行类的定义的上行
import 包名.类名;
50.API的使用
我们学习java编程面对2中类
-
我们自己写的类。
-
用其他人写好的类来使用。
API是把jdk里面提供好的类梳理成了一个文档,方便我们来查阅。
类的属性摘要
类的构造器摘要
类的方法摘要
、
从父类继承下来的方法
学习Math类
java中java.lang下面的所有类都不需要引入,可以直接来使用。
public class Demo{
public static void main(String[] args){
System.out.println(Math.E);//自然对数:Math.E 自然对数:Math.E
System.out.println(Math.PI);//圆周率:Math.PI 3.141592653589793
System.out.println(Math.abs(-1.5));//绝对值:Math.abs() 1.5
System.out.println(Math.ceil(12.1));//向上取整 Math.ceil() 13.0
System.out.println(Math.floor(12.9));//向下取整 Math.floor() 12.0
System.out.println(Math.max(12.9, 27));//比较两个数取最大值
System.out.println(Math.min(12.9, 27));//比较两个数取最小值
System.out.println(Math.pow(3, 3));//计算某个数的n次幂 Math.pow()
System.out.println(Math.round(4.5));//四舍五入 Math.round()
System.out.println(Math.sqrt(16));//开平方 Math.sqrt(16)
}
51.Scanner扫描器
运行程序的时候可以从控制台来输入数据。
Scanner的使用必须要引入这个类
scanner不属于Java.lang下必须引入包
常用构造方法
常用方法
import java.util.Scanner;
public class Demo1{
public static void main(String[] args){
//创建一个创建一个Scanner,调用构造器Scanner(InputStream source)
Scanner s=new Scanner(System.in);
//从控制台扫描一个int的数值
int score=s.nextInt();
if(score>95){
System.out.println("you are Amazing!");
}else if(score>80){
System.out.println("you are great!");
}else if(score>60||score==60){
System.out.println("you are good!");
}else if(score<60){
System.out.println("you lose!");
//从控制台扫描一个String的数值
String password=s.nextLine();
System.out.println("you write down"+password);