多态:即多种形态
例如:既可以成小王为老师,当然也可以成为人 。
例如:猫,既可以成为猫,也可以归为猫科动物,还可以归为动物
要从多个方面去理解一个事物就会发现事物的的多样性,所以就有了多态
多态要求:必须是有继承或实现的关系,(而且有方法重写)
语法格式:父类类型 变量名 = 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());
}