一、面向对象(多态)
可以理解为事物存在的多种体现形态。
人:男人,女人
动物:猫,狗。
猫 x=new 猫();
动物 x=new 猫();
1. 多态的基本体现:
父类的引用指向了自己的子类对象。
父类的引用也可以接受自己的子类对象。
2. 多态的前提:
必须是类与类之间有关系(要么继承,要么实现)。
通常还有一个前提:存在覆盖。
3. 多态的好处:
多态的出现大大的提高了程序的扩展性。
4. 多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
/*
动物:猫,狗
*/
abstract class Animal
{
public abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void lookHome()
{
System.out.println("看家");
}
}
class Pig extends Animal
{
public void eat()
{
System.out.println("吃饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*
Cat c=new Cat();// 1
c.eat();
Dog d=new Dog();
d.eat();
*/
/*
Cat c=new Cat();// 2
function(c);
function(new Dog());
function(new Pig());
*/
function(new Cat());// 3
function(new Dog());
function(new Pig());
}
public static void function(Animal a)
{
a.eat();
}
/*
public static void function(Cat c)
{
c.eat();
}
public static void function(Dog d)
{
d.eat();
}
public static void function(Pig p)
{
p.eat();
}
*/
}
二、面向对象(多态的转型)
/*
动物:猫,狗
*/
abstract class Animal
{
public abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void lookHome()
{
System.out.println("看家");
}
}
class Pig extends Animal
{
public void eat()
{
System.out.println("吃饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*
Animal a=new Cat();//类型的提升。也称为向上转型。
a.eat();
*/
/*强制将父类的引用转成子类类型。也称为向下转型。
Cat c=(Cat)a;
c.catchMouse();
*/
/*千万不要出现将父类的类型转换为子类类型。我们能
转换的是父类引用指向了自己的子类对象时,该引用可以
被提升,也可以被强制转换。多态自始至终都是子类对象
在做着变化.
例如:Animal a=new Animal();
Cat c=(Cat)a;
*/
function(new Cat());
function(new Dog());
}
public static void function(Animal a)
{
a.eat();
if(a instanceof Cat)// instanceof:判断所属类型。
{
Cat c=(Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog d=(Dog)a;
d.lookHome();
}
}
}
三、面向对象(多态示例)
/*
基础班的学生:学习,睡觉
高级班的学生:学习,睡觉
可以将这两类事物进行抽取。
*/
abstract class Student
{
public abstract void study();
public void sleep()
{
System.out.println("躺着睡");
}
}
class BaseStudent extends Student
{
public void study()
{
System.out.println("base study");
}
public void sleep()
{
System.out.println("坐着睡");
}
}
class AdvStudent extends Student
{
public void study()
{
System.out.println("adv study");
}
}
class DoStudent//工具类
{
public void doSomething(Student stu)
{
stu.study();
stu.sleep();
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
DoStudent ds=new DoStudent();
ds.doSomething(new BaseStudent());
ds.doSomething(new AdvStudent());
/*
BaseStudent bs=new BaseStudent();
bs.study();
bs.sleep();
AdvStudent as= new AdvStudent();
as.study();
as.sleep();
*/
}
}
四、面向对象(多态成员的特点)
在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过。否则编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结:成员函数在多态调用时,编译看左边,运行看右边。
在多态中成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数特点:
无论编译和运行,都参考左边。
/*
测试:
多态中成员的特点
*/
class Fu
{
int a=4;
static int b=5;
void method1()
{
System.out.println("fu method1");
}
void method2()
{
System.out.println("fu method2");
}
static void method4()
{
System.out.println("fu method4");
}
}
class Zi extends Fu
{
int a=5;
static int b=10;
void method1()
{
System.out.println("zi method1");
}
void method3()
{
System.out.println("zi method3");
}
static void method4()
{
System.out.println("zi method4");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Zi z1=new Zi();
z1.method1();
z1.method2();
z1.method3();
z1.method4();
System.out.println();
Fu z2=new Zi();
System.out.println(z2.a);
System.out.println(z2.b);
Zi z3=new Zi();
System.out.println(z3.a);
System.out.println(z3.b);
System.out.println();
Fu z4=new Zi();
z4.method4();
Zi z5=new Zi();
z5.method4();
}
}
五、面向对象(多态的主板示例)
/*
多态的主板示例:
*/
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("mainborad run");
}
public void usePCI(PCI p)//接口型引用指向自己的子类对象。
{
if(p!=null)
{
p.open();
p.close();
}
}
}
class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
class SoundCard implements PCI
{
public void open()
{
System.out.println("soundCard open");
}
public void close()
{
System.out.println("soundCard close");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
MainBoard mb=new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard());
mb.usePCI(new SoundCard());
}
}
六、面向对象(多态的扩展示例)
/*
需求:数据库的操作。
1.连接数据库
2.操作数据库(create delete update select)
3.关闭数据库连接
*/
interface UserInfoDao
{
public void add(User user);
public void delete(User user);
}
class UserInfoByJDBC implements UserInfoDao
{
public void add(User user)
{
1.连接数据库
2.使用SQL语句添加数据
3.关闭连接
}
public void delete(User user)
{
1.连接数据库
2.使用SQL语句删除数据
3.关闭连接
}
}
class UserHibernate implements UserInfoDao
{
public void add(User user)
{
1.连接数据库
2.使用SQL语句添加数据
3.关闭连接
}
public void delete(User user)
{
1.连接数据库
2.使用SQL语句删除数据
3.关闭连接
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
UserInfoDao ui1=new UserInfoByJDBC();
ui1.add(user);
ui1.delete(user);
UserInfoDao ui2=new UserHibernate();
ui2.add(user);
ui2.delete(user);
}
}
七、面向对象(Object类 – equeals())
Object:是所有对象的直接或间接父类。该类中定义的是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。如果沿袭父类中的功能,建立自己特有比较内容即可,这就是覆盖。
/*
覆盖Object类的equals方法。
public boolean equals(Object obj)
*/
class Demo
{
private int num;
Demo(int num)
{
this.num=num;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Demo))//判断类所属
return false;
Demo d=(Demo)obj;//向下转型
return this.num==d.num;
}
}
class Person
{
String name;
String age;
}
class ObjectDemo
{
public static void main(String[] args)
{
Demo d1=new Demo(5);
Demo d2=new Demo(6);
Demo d3=d1;
Person p=new Person();
System.out.println(d1.equals(d2));
System.out.println(d1.equals(p));
}
}
八、面向对象(Object类-toString())
toString
public String toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object 类的 toString方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
该对象的字符串表示形式。
/*
Object类的toString()方法。
*/
class Demo
{
private int num;
Demo(int num)
{
this.num=num;
}
}
class Person
{
String name;
String age;
}
class ObjectDemo
{
public static void main(String[] args)
{
Demo d1=new Demo(5);
System.out.println(d1.toString());
System.out.println(d1.getClass().getName()+"@"+Integer.toHexString(d1.hashCode()));
}
}
/*
覆盖Object类的toString()方法。
*/
class Demo
{
private int num;
Demo(int num)
{
this.num=num;
}
public String toString()//覆盖Object类toString方法
{
return this.getClass().toString()+num;
}
}
class ObjectDemo
{
public static void main(String[] args)
{
Demo d1=new Demo(5);
Demo d2=new Demo(6);
Demo d3=new Demo(7);
System.out.println(d1.toString());
System.out.println(d2.toString());
System.out.println(d3.toString());
}