------- android培训、java培训、期待与您交流! ----------
封装和继承已经谈论的差不多了!现在来看看java中最后一个特性多态。
多态:
定义:某一类事物的多种存在形式。
例如:动物中的猫,狗。
猫这个对象对应的类型应该是猫类型。
猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫成为动物。
动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
1、多态的基本体现。
父类的引用指向了自己的子类对象。
父类的引用也可以接受自己的子类对象。
2、多态的前提。
必须是类与类之间有关系,要么继承,要么实现。
通常还有一个前提,存在覆盖。
3、多态的好处。
多态的出现大大的提高了程序的扩展性。
4、多态的弊端。
提高了扩展性,但是只能使用父类的引用访问访问父类中的成员。
5、多态的应用
下面通过一个例子来说明多态的事迹体现。
abstract class Animal//动物类
{
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 kanJia()
{
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();//和数据类型的强转一样,byte b = 2, int x= b;差不多。专业属于叫做向上转型。
a.eat();
//如果想要调用猫的特有方法时,如何操作。
//强制将父类的引用,转成子类型。向下转型。
Cat c = (Cat)a;
c.catchMouse();
/*
千万不要出现这样的操作,就是将父类对象转成子类类型。
我们能转换的是父类引用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
至始至终都是子类对象在做着变化。
Animal a = new Animal();
Cat a = (Cat)a;
*/
}
public static void function(Animal a)
{
a.eat();
//一般不用这种方法子类型一多该程序扩展性很差。
if(a instanceof Cat)//判断a是不是属于猫这个类型!
{
Cat c = (Cat)a;
c.catchMouse(); //实现子类的特有的方法、
}
else if (a instanceof Dog)//判断a是不是属于狗这个类型!
{
Dog d = (Dog)a;
d.kanJia();
}
}
}
上面很好的提到了多态的应用,父类引用指向了子类对象。
这个举个很简单的例子可以说明这个问题,
人类从祖先哪儿集成到了抓鱼这个属性,但是古人抓鱼或许是用双手或者树杈,而现在我们可以用手抓,可以用鱼竿,可以用渔网。
是不是同样是抓鱼我们用到了不同的体现方式。而且可以在不同的环境复写抓鱼这个方法,来实现不同的过程已达到相同的目的。
多态有了大概的理解那么我们来看看
在多态中成员(非静态)函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。
class Fu
{
int num = 5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
static void method4()
{
System.out.println("fu method_4");
}
}
class Zi extends Fu
{
int num = 8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
}
static void method4()
{
System.out.println("zi method_4");
}
}
class DuoTaiDemo2
{
public static void main(String[] args)
{
Fu f = new zi();
f.method4();
//Fu f = new Zi();
//System.out.println(f.num);//5
//Zi z = new Zi();
//System.out.println(z.num);//8
//
//f.method1(); 运行zi method_1
//f.method2(); 运行fu method_2
/*
f.method3();
编译失败,找不到method3();因为在Fu类中并没有method3这个方法。
*/
/*
Zi z = new Zi();
z.method1();
z.method2();
z.method3();
*/
System.out.println("Hello World!");
}
}
这个就体现出来了函数中多态对各个变量,函数之间的调用关系。
我们从下面这个小例子中在来看看多态的应用。
多态的主板示例:
interface PCI//定义一个对外的接口
{
public void open();
public void close();
}
class MainBoard //定义一个主板类
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p)//PCI p = new PCI() 接口型引用指向自己的子类对象。
{
if(p != null)
{
p.open();
p.close();
}
}
}
class NetCard implements PCI<span style="font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', SimSun, 'Segoe UI', Tahoma, Helvetica, sans-serif, 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif;">//网卡继承了上诉接口实现了打开与关闭方法</span>
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
class SoundCard implements PCI<span style="font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', SimSun, 'Segoe UI', Tahoma, Helvetica, sans-serif, 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif;">//声卡继承了上诉接口实现了打开与关闭方法</span>
{
public void open()
{
System.out.println("soundcard open");
}
public void close()
{
System.out.println("soundcard close");
}
}
class DuoTaiDemo3
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(new NetCard());
mb.usePCI(new SoundCard());
}
}
在以后的应用中我们会用到很多种类的数据库,我们也顺便看看关于数据库的多态应用
/*
需求:数据库的操作。
数据:用户信息。
1、连接数据库。
2、操作数据库。
c create r read u update d delete
3、关闭数据库。
*/
interface UserInfoDao
{
public static void add(User user);
public static void delete(User user);
}
class UserInfoByJDBC implements UserInfoDao
{
public void add(User user)
{
/*
1、JDBC连接数据库
2、使用sql添加语句添加数据。
3、关闭连接。
*/
}
public void delete(User user)
{
/*
1、JDBC连接数据库
2、使用sql删除语句删除数据。
3、关闭连接。
*/
}
}
class UserInfoByHibernate implements UserInfoDao
{
public void add(User user)
{
/*
1、Hibernate连接数据库
2、使用Hibernate添加语句添加数据。
3、关闭连接。
*/
}
public void delete(User user)
{
/*
1、Hibernate连接数据库
2、使用Hibernate删除语句删除数据。
3、关闭连接。
*/
}
}
class DBOperate
{
public static void main(String[] args)
{
//UserInfoByJDBC ui = new UserInfoByJDBC();
//UserInfoByHibernate ui = new UserInfoByHibernate();
UserInfoDao ui = new UserInfoByJDBC();
ui.add(user);
ui.delete(user);
System.out.println("Hello World!");
}
}
class UserInfoByJDBC
{
public void add(User user)
{
/*
1、JDBC连接数据库
2、使用sql添加语句添加数据。
3、关闭连接。
*/
}
public void delete(User user)
{
/*
1、JDBC连接数据库
2、使用sql删除语句删除数据。
3、关闭连接。
*/
}
}
class UserInfoByHibernate
{
public void add(User user)
{
/*
1、Hibernate连接数据库
2、使用Hibernate添加语句添加数据。
3、关闭连接。
*/
}
public void delete(User user)
{
/*
1、Hibernate连接数据库
2、使用Hibernate删除语句删除数据。
3、关闭连接。
*/
}
}
class DBOperate
{
public static void main(String[] args)
{
//UserInfoByJDBC ui = new UserInfoByJDBC();
UserInfoByHibernate ui = new UserInfoByHibernate();
ui.add(user);
ui.delete(user);
System.out.println("Hello World!");
}
}
Object:是所有对象的直接或者间接父类。
该类中定义的肯定是所有对象都具备的功能。
equals:
class Demo //extends Object
{
private int num;
Demo(int num)
{
this.num = num;
}
public boolean equals(Object obj)//obj中没有定义num所以需要向下转型。
{
if(obj instanceof Demo)//需要判断obj是不是属于demo类
return false();
Demo d = (Demo)obj;//如果是就需要向下转型成为Demo类型、
return this.num == d.num;
}
}
class Person
{
}
class ObjectDemo
{
public static void main(String[] args)
{
Demo d1 = new Demo(4);
Demo d2 = new Demo(4);
Person p = new Person();
System.out.println(d1.equals(d2));
}
}
这个就是Object中的equals,Java中Object认为所有事物都具有比较性,他们之间都能记性各种不同类型的比较。比如体积的比较,重量的比较。
其中还有一个就是toString()
先看一下Object类中的toString()方法源码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
它是打印了类名和内存地址的一个方法。但是String里面的toString()就是String重写了Object里面的toString()方法,使得打印出来的为
一个字符串。下面通过一个小例子来理解一下。
public class ObjectTest{
public static void main(String[] args) {
//处理常见数据类型
String text="22";
System.out.println(text); //输出:22
//处理Student对象,没有重写toString()方法
Student stu=new Student("学生");
System.out.println(stu); //输出:Student@c17164
System.out.println(stu.name); //输出:学生
//处理Teacher对象,重写toString()方法
Teacher tea=new Teacher("老师");
System.out.println(tea); //输出:老师
System.out.println(tea.name); //输出:老师
}
}
//Student类
class Student{
String name;
public Student(String name) {
this.name = name;
}
}
//Teacher类
class Teacher{
String name;
public Teacher(String name) {
this.name = name;
}
public String toString()
{
return name;
}
}
这个就是面向对象的多态的应用以及相关的知识点,下面我将给大家谈谈面向对象的一个异常处理和内部类的应用。面向对象就差不多完了。重要的是要多理解。通过理解去记忆而非死记硬背。
------- android培训、java培训、期待与您交流! ----------
详细请查看:www.itheima.com