多态和接口Api(1)

多态:即多种形态

例如:既可以成小王为老师,当然也可以成为人 。

例如:猫,既可以成为猫,也可以归为猫科动物,还可以归为动物
要从多个方面去理解一个事物就会发现事物的的多样性,所以就有了多态
多态要求:必须是有继承或实现的关系,(而且有方法重写)
语法格式:父类类型 变量名 = new 子类类型()

public class DuoTaiDemo {
	public static void main(String[] args) {

		// 多态的前提下,子父类中方法及属性的调用限制问题
		// 子类既可以使用自身的特殊方法,也可以使用父类中提供的方法
		//结果:子类可以调用父类的方法,但是父类不允许调用子类的方法的
		Cat cat = new Cat();
		cat.catchMouse();
		cat.sleep();

		// 默认的多态的形式称为向上转型,限制了对子类中特有方法的使用
		Animal animal = new Cat();
		animal.eat();
		animal.sleep();

		// 向下转型,为了使用子类中的特有方法
		// int a = 1; byte b = (byte)a;
		Cat cat2 = (Cat) animal;
		cat2.catchMouse();
	}
语法:**父类数据类型 变量名 = new 子类数据类型();**
public static void main(String[] args){
    //向上转型,该变量就只能调用父类中也有的方法,而不能去调用子类中特有的方法
    CatKinds ck = new Cat();
    ck.sleep();
    //ck.eatfish();
    
    /*Cat cat = new Cat();
    cat.sleep();
    cat.a();
    cat.b();
    cat.c();
    Tiger tiger = new Tiger();
    tiger.sleep();
    tiger.a();
    tiger.b();
    tiger.c();*/
    Cat cat = new Cat();
    show(cat);
    Tiger tiger = new Tiger();
    show(tiger);
    byte b = 1;
    baseShow(b);//int a = 1
    animalShow(cat);
}
//猫科动物在睡觉--下述案例纯粹只是为了掩饰知识点
public static void show(CatKinds ck){//CatKinds ck = new Cat(); CatKinds ck=new Tiger();
    ck.sleep();
    ck.a();
    ck.b();
    ck.c();
    //如果在调用了公共的方法后需要去调用子类特有的方法,怎么办---强制类型转换
    //需要使用instanceof 判断引用数据类型
    if(ck instanceof Cat){
        Cat cat = (Cat)ck;
        cat.eatFish();
    }else if(ck instanceof Tiger){
        Tiger tiger = (Tiger)ck;
        tiger.king();
    }
}
public static void animalShow(Animal animal){//Animal animal = new Cat();
    animal.breath();
}

public static void baseShow(int a){
    byte c = (byte)a;
}

public static void show(Cat cat){
    cat.sleep();
    cat.a();
    cat.b();
    cat.c();
}
public static void show(Tiger tiger){
    tiger.sleep();
    tiger.a();
    tiger.b();
    tiger.c();
}

Object obj = new Cat();
问题1:obj.eatFish();是否有问题,为什么?
Cat向上转型为Object,限制了对子类中特有方法的调用
问题2:System.out.println(obj.toString()); 是否有问题,为什么?
没有问题,Object中有toString()方法

总结:

向上转型:目的是为了限制对子类中特有方法的调用

向下转型:目的是为了调用子类中特有的方法

思考:在多态的情况下,子类和父类中的变量有什么区别?

编译时期看父类中是否存在,存在就编译通过,不存在就编译失败

执行的时候,执行的是父类中的变量,原因是向上转型时,只能调用父类中提供的公共的属性或方法

思考:在多态的情况下,子类和父类中的静态方法有什么区别?

编译时期看父类中是否存在该方法,存在就编译通过,不存在就编译失败

编译时期执行的是父类中的方法,原因是向上转型时,只能调用父类中提供的公共的属性或方法

思考:在多态的情况下,子类和父类中的非静态方法有什么区别?

编译时期看父类中是否存在该方法,存在就编译通过,不存在就编译失败

执行时期执行子类中的方法


**API**

Math对象
数学函数类,类是最终类不能被继承,其中的方法都是静态方法,类名直接调用即可

/**
 * ceil()				求大于或等于给定值的最小整数	向上取
 * floor()				求小于或等于给定值的最大整数	向下取
 * random()				生成一个0~1之间的小数
 */
public class MathDemo {

	public static void main(String[] args) {
		System.out.println("圆周率:"+Math.PI);
		System.out.println("向上取:"+Math.ceil(11.5));
		System.out.println("向下取:"+Math.floor(-11.5));
		System.out.println("随机数:"+Math.random());
		System.out.println("1~10:"+Math.random()*10+1);
		System.out.println("1~10:"+Math.ceil(Math.random()*10));
		System.out.println("0~9:"+Math.floor(Math.random()*10));
		
		String[] nameArrs = {"张三","赵四","李二"};
		int index = (int) Math.floor(Math.random()*nameArrs.length);
		System.out.println(index+","+nameArrs[index]);
	}
}

Object类
该类为所有类的超类,默认是省略的

public class ObjectMethod {
	public static void main(String[] args) {
		Test test = new Test();
		System.out.println("获取到运行时类的路径(不准确):"+test.getClass());
		System.out.println("hashCode值:"+test.hashCode());
		//hashCode值可以理解为对象的地址
		Test test2 = new Test();
		System.out.println(test2.hashCode());
		//toString() 默认返回该对象的路径+地址 自动调用
		System.out.println(test.toString());
		System.out.println(test);
		//equals() 比较两个对象是否相等
		Test test3 = test;
		System.out.println(test == test2);
		System.out.println(test == test3);
		System.out.println(test.equals(test2));
		System.out.println(test.equals(test3));
	}
```java
public class ObjectDemo {
	public static void main(String[] args) {
		User user = new User(13,"小黑","1325645458","1576765567");
		//System.out.println(user.getAge()+"--"+user.getName()+"--"+user.getIdCard()+"--"+user.getPhone());
		System.out.println(user);
		System.out.println(user.toString());
		
		User user2 = new User();
		User user3 = new User();
		User user4 = user2;
		System.out.println(user2 == user3);
		System.out.println(user2 == user4);
		System.out.println(user2.equals(user3));
		System.out.println(user2.equals(user4));
		
		int a = 4;
		int b = 5;
		System.out.println(a == b);
		//总结:==用于基本数据类型时比较的是值,用于引用数据类型时比较的是地址
		//总结:equals方法对于没有重写的引用数据类型而言是用于比较地址的
	}
}
class User{
	private int age;
	
	private String name;
	
	private String idCard;
	
	private String phone;
	
	public User() {}

	public User(int age, String name, String idCard, String phone) {
		super();
		this.age = age;
		this.name = name;
		this.idCard = idCard;
		this.phone = phone;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getIdCard() {
		return idCard;
	}

	public void setIdCard(String idCard) {
		this.idCard = idCard;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + ", idCard=" + idCard + ", phone=" + phone + "]";
	}
	
}

}

**String类**
	String是引用数据类型,表示字符串(其实是由多个字符组成的)
	String是final修饰的,所以是最终类,最终类是不能被继承的,既然不能被继承也就意味着里面的方法不能被重写
	字符串本身是引用数据类型,可以通过new关键字进行对象的创建
	字符串又比较特殊,它也可以直接赋值的形式进行字符串对象的创建
	上述的区别在哪里呢?
	 API中说明:字符串都是常量
	字符串常量池:
		字符串常量池:字符串是常量,所有的字符串常量都是存储在常量池中的,每个常量在常量池中都有地址;在常量池中,如果定义的常量在常量池中已经存在,则不会再进行创建,而是直接拿来用,如果不存在就创建一个常量扔进常量池中
```java
public static void method4() {
		String str = new String("haha");
		String str2 = new String("haha");
		System.out.println(str == str2);//false
		String str3 = "hehe";
		String str4 = "hehe";
		System.out.println(str3 == str4);//true
		System.out.println("------");
		
		String str6 = "hello";
		String str7 = "world";
		String str8 = "helloworld";
		String str9 = str6 + str7;//对已经创建好的对象进行了拼接
		System.out.println(str8 == str9);//false
		System.out.println(str8.equals(str9));//true
		System.out.println("------");
		
		String str0 = "a"+"b"+"c";//先拼接再创建对象
		String str01 = "abc";
		System.out.println(str0 == str01);
		System.out.println(str0.equals(str01));
	}

1.地址判断
2.将传递过来的字符串转换为字符数组,判断长度是否相同
3.根据下标的位置,逐个比较字符是否相同
面试题:==和equals的区别
*==用于基本数据类型时比较的是值,用于引用数据类型比较的时地址
* equals在字符串中是先比较地址后比较内容

public static void method3() {
		//equals() 重写了Object中的equals方法,先比较地址,地址不同,然后比较内容,地址相同就直接返回true
		String str = new String("hello");
		String str2 = new String("hello");
		System.out.println(str == str2);//false 地址不同
		System.out.println(str.equals(str2));//true
	}

String中有用的且常用的方法

public static void method2() {
		// replace() 替换
		String url = "http://www.news.baidu.com";
		String newUrl = url.replace("baidu", "jd");
		System.out.println(newUrl);
		// substring() 截取 如果只有一个参数,代表开始,直到末尾结束
		System.out.println(url.substring(7));
		// substring() 截取 如果有两个参数,参数一代表开始,参数二代表结束位置(不包含)
		System.out.println(url.substring(7, url.length()));
		// split() 分割 参数代表要拆分的依据 \\.
		String[] urlArr = url.split("\\.");
		System.out.println(urlArr[urlArr.length - 2]);
		System.out.println("转换为纯大写:" + url.toUpperCase());
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值