浅聊Java
从面向对象设计思想开始,一路高歌。
众所周知,Java是一门面向对象的编程语言,是站在C语言的肩膀上发展起来的。
C语言为什么难以理解?正是因为它具有多继承、指针,内存回收等复杂操作才使得C语言相比Java而言更加臃肿,而Java就显得更加强大简单。
面向对象相比于面向过程到底强在哪里?
这里可以举个比较例子,解释面向对象编程。
比如我要开车去XX:
面向过程设计思想:我开车、挂挡、踩油门、过xx省,xx路;
面向对象设计思想:我命令车这个对象带我去,我不管怎么去,只要能到。
概念: 不要记概念。 面向对象更加贴近人的思维方式,因为我人类眼睛看到的就是一个个对象,比如一个茶壶,而且这个茶壶能够做很多事情。
面向过程是对汇编的抽象。
面向对象是对现实问题的抽象。-------更加符合人类行为。
对象都有对外服务的接口-----通过继承可以复用,对象隐藏内部服务的实现----通过聚合可以复用。
既然聊到这里,为何不将目光转至继承? 这里要明白一点,继承虽然是面向对象编程语言的特点,但是它不仅仅属于面向对象编程语言。
官腔:继承是子类自动共享父类数据和方法的机制,这是类之间的关系,提高了软件的可重用性与可扩展性。
一谈是什么什么机制,就会显得你读书多,呵呵哒。
你只知道子类继承父类,就可以共享父类数据,实现功能复用,再深一些的话,不如从内存结构来说明。
举个例子:
父类Person(有name,age),子类Student(有school)。 子类继承父类。
java代码可以表示为
Person student = new Student();
众所周知,变量会分布在栈中的变量表中,对象会被开辟在堆内存中。画结构分布图:
student首先拥有person所有信息,然后还有属于自己的信息;这里就体现了继承的可重用性,name,age我只需要在父类中写一遍。
事实上讲,student大于person;
当new一个student时,其实student对象内部还有一个父类对象person。
所以,子类对象包含父类对象。
需要说明的两点:
- 子类的构造方法必须调用父类的构造方法,而且super()要放在子类构造方法里的第一行。(有父才有子)
- 如果子类没有显示调用父类super()(创建出父类),系统默认子类调用父类无参构造方法。(有父才有子)
既然聊到这里,不如再说说多态?为什么能引出多态?在上述的一段java代码示例中,我创建的student对象是以Person类型接收的。
多态实际也叫做动态绑定,很多人不理解在Java中为什么会有动态与静态之说,比如静态链接动态链接。
其实所谓动态与静态的区分只在于一点:代码的编译期(静态)与执行期(动态)。
一句话概括多态:在执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应方法。
多态的重点在于:子类继承父类,重写父类方法来实现多态。 所以说,多态实际是在子与父之间诞生的。
如果觉得还不够,我们可以举一个在Java开发中常用的例子:开发中的三层架构。
建立dao层接口: MyDao ,在接口中定义一个方法print();
建立业务层实现类: MySqlService、OracleService、 分别实现myDao接口。
在子类mysqlService与OracleService中分别重写父接口myDao方法中的print()。
抽象出来一个公用方法
public void comeIn(MyDao mydao){
myDao.print();
}
可以发现,如果调用comeIn方法,它的类型是MyDao,在编译期间是无法确定具体类型的,在程序员调用comeIn() 时,可以传mysqlService 也可以传OracleService进去。
这个方法comeIn()起初是不知道你传的到底是什么类型的,它只认识Mydao类型。但是当程序一运行起来,comeIn方法才能知道程序员到底传进来的是谁,又该调用谁的print()方法。
这里可以再解释一下向上转型与向下转型,当你明白一个多态例子在内存中的分布结构时,这个就不难理解。
Student student = new Person(); 向下转型: 我拥有你的全部信息,new出一个你很难吗?
Person person = (Student)new Student(); 向上转型: 很难,这里需要强转了。
写着写着就不想写了,想接着说指针的。算了,唉年轻就是这样,总是多愁善感,突发奇想。