Java面对对象(多态)
一,object类和toString
Object 类|老祖宗类
是java 中所有类的父类
在java中的所有类都会直接或者间接的继承自Object类
toString() 把对象数据以字符串的形式表示
直接打印一个对象的引用的时候,默认打印的是调用toString()方法的返回值
需求:
在打印一个javabean类型的对象的引用的时候,其实想要了解这个对象的基本信息–成员变量的值
解决:
在子类中重写toString方法,因为打印对象引用时候默认会调用toString().toString功能需要,实现不满意,就重写.
package lianxi;
public class Class_toString {
public static void main(String[] args) {
Person person=new Person();
person.setAge(16);
person.setName("王二小");
System.out.println(person);
Boy boy=new Boy("红色");
boy.setAge(14);
boy.setName("王小二");
System.out.println(boy);
}
}
class Person{
private String name;
private int age;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Boy extends Person{
private String color;
public Boy(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Boy{" +
"color='" + color + '\'' +
'}'+super.toString();
}
}
二,equals()
equals()
==可以比较所以的数据类型的数据,基本数据类型–数据值
引用数据类型–比较对象地址
equals 只能比较引用数据类型的数据
比较两个数据是否相等 对象1.equals(对象2)
Object类中equals方法的实现—默认比较对象的地址,可以通过重写equals方法实现比较对象的内容
需求:
比较两个引用数据类型对象的时候,想要比较两个对象的所有成员变量的值是否都相等,而非比较对象地址
解决:子类中重写equals方法,实现比较对象内容非地址.
public class Class_equals {
public static void main(String[] args) {
Person1 per=new Person1("王二",12);
Person1 per1=new Person1("王二",35);
System.out.println(per.equals(per1));
System.out.println(per.getName().equals(per1.getName()));
}
}
class Person1{
private String name;
private int age;
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person1{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
三,多态
多态--------面向对象的三大特性之一
多种形态–多种表现方式
多态的最终体现:
父类的引用指向子类的对象
多态的前提:
继承关系
实现关系
多态的使用:
当多态调用的时候,会调用子类中的重写方法
多态调用成员的特点:
成员变量:
编译运行看父类|左边|类型
成员方法:
编译看父类,运行找子类
编译看左边,运行找右边
编译看类型,运行找对象
public class Class_Ploy {
public static void main(String[] args) {
Person01 p1=new Sone();
System.out.println(p1.name);
p1.work01();
}
}
class Person01 {
public String name="小明";
public void work01() {
System.out.println("打酱油");
}
}
class Sone extends Person01 {
public String name;
public Sone() {
}
public void work01() {
System.out.println("程序猿");
}
父类引用指向子类对象
多态: 行为的多态,行为的不同实现方式
行为->方法->方法的重写多态需要配合方法的重写才有意义
多态引用对子类新增内容不可见
多态的好处:
解耦 :
灵活性
便于后期维护
package lianxi;
public class Class_poly2 {
public static void main(String[] args) {
FU f=new Er();
f.work();
System.out.println(f.name);
Er g=new Sun();
g.eat01();
}
}
class FU{
public String name="Fu";
public void work(){
System.out.println("work");
}
}
class Er extends FU{
public String name="Er";
public int age =12;
public void work(){
System.out.println("work1");
}
//新增
public void eat01(){
System.out.println("用手吃饭");
}
}
class Sun extends Er{
public String name="sun";
public void eat01(){
System.out.println("用筷子吃饭");
}
}
四,转型
基本数据类型 :
自动类型提升 : 小–>大
int i = ‘a’;
强制类型转换 : 大–>小
byte b = (byte)i;
转型:
引用数据类型:
父类->大
子类->小
向上转型: 小->大
Person p = new Student();
向下转型: 大->小
Student s = (Student)p;通过多态的引用调用子类中新增内容的时候,需要向下转型
举例子:
孔子爹类 :
class KongZiDie{ void teach(){做生意} } 孔子类 继承 孔子爹
class KongZi extends KongZiDie{ void teach(){论语…} void play(){吃鸡…}} 有一个人来找孔子爹请他去讲课,可以,孔子爹外出,想办法:
让孔子化妆,装成他爹的样子,去讲课
KongZiDie k = new KongZi(); --> 向上转型
k.teach(); 孔子与班级同学想要一起玩游戏,因为孔子爹不会玩游戏->
卸妆->变成孔子样子,才能调用孔子的能力->play
KongZi kk = (KongZi)k; -->向下转型 kk.play();
注意:
向下转型时候,如果类型不注意,就有可能出现ClassCastException类型转换异常 instanceof 运算符–>避免遇到类型转换异常
引用 instanceof 类型 : 判断前面的引用是否是指向后面类型的对象|子类对象->是true | 不是false
public class Class003_Cast {
public static void main(String[] args) {
KongziDie k = new Brother();
k.teach();
//向下转型
if(k instanceof Brother){
Brother kk = (Brother)k; //Brother kk = new Kongzi();
kk.play();
}else if (k instanceof Kongzi){
Kongzi kk = (Kongzi)k; //Kongzi kk = new Kongzi();
kk.play();
}
System.out.println(k instanceof Object); //true
System.out.println(k instanceof KongziDie); //true
System.out.println(k instanceof Brother); //true
System.out.println(k instanceof Kongzi); //false
}
}
class KongziDie{
void teach(){
System.out.println("做生意...");
}
}
class Kongzi extends KongziDie{
void teach(){
System.out.println("论语...");
}
void play(){
System.out.println("吃鸡...");
}
}
class Brother extends KongziDie{
void teach(){
System.out.println("讲笑话...");
}
void play(){
System.out.println("LOL...");
}
}
五.抽象
抽象类与抽象方法
抽象方法: 被abstract修饰的方法
没有方法体
要求定义在抽象类中
抽象类: 被abstract修饰的类父类:
具体的父类 : 普通的类,类中所有的方法必须存在实现(方法体)
抽象的父类 : 抽象类,可以存在具体方法,可以存在抽象方法抽象类特点:
1.抽象类中可以存在具体方法,可以存在抽象方法
可以存在成员变量,构造器…
2.抽象类不能实例化(不能创建对象)
3.一个抽象方法必须被重写,重写可以为抽象方法定义方法体
4.抽象类的使用: 通过具体子类的对象使用
具体的子类 : 重写了所有抽象方法+按需新增
抽象的子类 : 按需重写抽象方法+按需新增
5.一个抽象方法一旦被重写,后续是否需要重写根据实现
6.abstract关键字不能与private,final,static,native一起使用
public class Class001_abstract {
public static void main(String[] args) {
//测试抽象类是否能够实例
//Develop d = new Develop();
//具体子类
Java java = new Java();
java.work();
java.sleep();
java.haha();
Demo demo = new Demo();
demo.work();
demo.sleep();
demo.haha();
}
}
//开发部门
//抽象父类
abstract class Develop{
//方法体work不知道怎么写,不知道写什么->不写
abstract void work();
//普通方法
void sleep(){
System.out.println("闭着眼睛睡觉");
}
}
//java程序猿 : 服务器端开发
//具体子类
class Java extends Develop{
@Override
void work() {
System.out.println("服务器端开发");
}
void sleep(){
System.out.println("变敲代码边睡觉");
}
//新增方法
void haha(){
System.out.println("哈哈哈傻笑");
}
}
//web攻城狮 : 浏览器开发
//抽象子类
abstract class Web extends Develop{
void haha(){
System.out.println("美美的笑....");
}
}
//具体子类
class Demo extends Web{
@Override
void work() {
System.out.println("Demo中的work");
}
}