一、Java编程思想之对象入门

  • 前言
  • 1、面向对象程序设计
  • 2、接口的由来----接收请求
  • 3、public,private,protected的由来----实现方案的隐藏
  • 4、成员对象的由来----方案的重复使用
  • 5、继承的由来----重新使用接口
    • 5.1、继承特点:
    • 5.2、继承关键字
      • 5.2.1、extends与 implements关键字
      • 5.2.2、super 与 this 关键字
      • 5.3.3、final关键字
    • 5.3、重写和重载
      • 5.4、上溯造型和下塑造型
  • 6、抽象类的由来----限制基础类只为自己的衍生类提供一个接口,不允许创建一个自己的实例
  • 7、对象的创建和存在时间----对象需要的数据位于哪儿,如何控制对象的“存在时间”呢?
    • 7.1集合与继承器----不知道需要对象个数、存活时间,如何保存呢?
  • 最后

前言

重写梳理一下Java基础知识,结合着《Java编程思想》,思考为什么要这样?


1、面向对象程序设计

(1) 所有东西都是对象。可将对象想象成一种新型变量;它保存着数据,但可要求它对自身进行操作。
(2) 程序是一大堆对象的组合;通过消息传递,各对象知道自己该做些什么。
(3) 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。
(4) 每个对象都有一种类型。一个类最重要的特征就是“能将什么消息发给它?”。
(5) 同一类所有对象都能接收相同的消息。

2、接口的由来----接收请求

如何利用对象完成真正有用的工作呢?必须有一种办法能向对象发出请求,令其做一些实际的事情,比如完成一次交易、在屏幕上画一些东西或者打开一个开关等等。
每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的“接口”(Interface)定义的,对象的“类型”或“类”则规定了它的接口形式。

3、public,private,protected的由来----实现方案的隐藏

从根本上说,大致有两方面的人员涉足面向对象的编程:“类创建者”(创建新数据类型的人)以及“客户程序员”。对类创建者来说,他们的目标则是从头构建一个类,只向客户程序员开放有必要开放的东西(接口),其他所有细节都隐藏起来。因此便有了public,private,protected 以及暗示性的friendly。

4、成员对象的由来----方案的重复使用

新类可由任意数量和类型的其他对象构成。这个概念叫作“组织”——在现有类的基础上组织一个新类。对象的组织具有极大的灵活性。新类的“成员对象”通常设为“私有”(Private),使用这个类的客户程序员不能访问它们。这样一来,我们可在不干扰客户代码的前提下,从容地修改那些成员。也可以在“运行期”更改成员,这进一步增大了灵活性。

后面要讲到的“继承”并不具备这种灵活性。因此新建类的时候,首先应考虑“组织”对象;这样做显得更加简单和灵活。

5、继承的由来----重新使用接口

多种数据类型,令其实现大致相同的功能,代码量大且臃肿。但若能利用现成的数据类型,对其进行“克隆”,再根据情况进行添加和修改就好了。“继承”正是针对这个目标而设计的。
公共父类:

public class Animal { private String name;  private int id; public Animal(String myName, int myid) { name = myName; id = myid;} public void eat(){ System.out.println(name+"正在吃"); }public void sleep(){System.out.println(name+"正在睡");}public void introduction() { System.out.println("大家好!我是"         + id + "号" + name + "."); }
}

企鹅类:

public class Penguin extends Animal { public Penguin(String myName, int myid) { super(myName, myid); }
}

老鼠类:

public class Mouse extends Animal { public Mouse(String myName, int myid) { super(myName, myid); }
}

5.1、继承特点:

(1)子类拥有父类非 private 的属性、方法。
(2)子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
(3)子类可以用自己的方式实现父类的方法。
(4)类的继承是单一继承。
(5)提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)

5.2、继承关键字

5.2.1、extends与 implements关键字

extends 只能继承一个类,类的继承是单一继承。
implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口。

5.2.2、super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。

5.3.3、final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写。
注:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final。

5.3、重写和重载

5.4、上溯造型和下塑造型

方法的重写、重载与动态连接构成多态性。Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承。

我定义了一个子类Cat,它继承了Animal类。我可以通过 Cat c = new Cat(); 实例化一个Cat的对象。但当我这样定义时: Animal a = new Cat(); 这代表什么意思呢?

它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。那么这样做有什么意义呢?

因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。

public class Test {public static void main(String[] args) {show(new Cat());  // 以 Cat 对象调用 show 方法show(new Dog());  // 以 Dog 对象调用 show 方法Animal a = new Cat();  // 向上转型  a.eat();               // 调用的是 Cat 的 eatCat c = (Cat)a;        // 向下转型  c.work();        // 调用的是 Cat 的 work}  public static void show(Animal a)  {a.eat();  // 类型判断if (a instanceof Cat)  {  // 猫做的事情 Cat c = (Cat)a;  c.work();  } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a;  c.work();  }  }
}abstract class Animal {  abstract void eat();
}  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void work() {  System.out.println("抓老鼠");  }
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");  }  public void work() {  System.out.println("看家");  }
}程序输出:
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠

下面我们看另外一个例子:

/*** @author WangQun* 动物抽象类*/
abstract class Animal {public abstract void speak();public void eat(){// 闷头吃,不做额外的事情 }
} /*** @author WangQun*    门神接口*/
interface DoorGod {void guard();
} /*** @author WangQun* 猫,继承自动物*/
class  Cat  extends  Animal {@Overridepublic   void  eat() {try  {Thread.sleep( 1000 );}  catch  (InterruptedException e) {e.printStackTrace();}super .eat();}@Overridepublic   void  speak() {System.out.println( " 喵喵 " );}}/*** @author WangQun* 狗,继承自动物,实现门神接口*/
class  Dog  extends  Animal  implements  DoorGod{@Overridepublic   void  speak() {System.out.println( " 汪汪 " );}public   void  guard() {while ( true ){System.out.println( " 汪汪 " );}}}

其中Animal为基类,定义speak和eat方法,eat方法给出了空实现; DoorGod为门神接口,定义了 guard方法来守护家门; Cat为继承Animal的子类,这里假定猫有挑食的习惯,在eat中要耽搁点时间看看伙食;Dog也为继承Animal的子类,同时它实现了DoorGod接口来守护家门。

先说说上溯造型(upcasting)。这个术语缘于继承关系图的传统画法:将基类至于顶部,而向下发展的就是派生类。根据上面的sample,我给出下面的一个小应用:

public class Main {/*** @param animal* 上溯,传入的参数强制转换成其父类*/public static void upcasting(Animal animal){animal.speak();animal.eat();}public static void main(String[] args) {Animal dog1 = new Dog();upcasting(dog1);Dog dog2 = new Dog();upcasting(dog2);}}

由于upcasting(Animal animal)方法的参数是 Animal类型的,因此如果传入的参数是 Animal的子类,传入的参数就会被转换成父类Animal类型,这样你创建的Dog对象能使用的方法只是Animal中的签名方法;也就是说,在上溯的过程中,Dog的接口变窄了,它本身的一些方法(例如实现了 DoorGod的guard方法)就不可见了。如果你想使用Dog中存在而Animal中不存在的方法(比如guard方法),编译时不能通过的。由此可见,上溯造型是安全的类型转换。另一方面,虽然upcasting(Animal animal)方法的参数是 Animal类型,但传入的参数可以是Animal的派生类(这也是OO编程中惯用的编程方法),这里面就有个对象的类型识别问题,也就是运行时类型识别(run-time type identification,缩写为RTTI) ,这也可以单独写一篇文章了,《Thinking in Java》中的第10章详细地阐述了RTTI。

相对于类型转换安全的上溯造型,下溯造型就未必是安全的了。我们经常会做些强制类型转换的事情,有时我们也会无意间遇到 ClassCastException的转换异常(从这一点来说,我们应该多用范型来避免不安全的类型转换)。例如:

public static void downcasting(Animal animal){//判断类是不是实现自哪个接口if(animal instanceof DoorGod){DoorGod doorGod = (DoorGod)animal;doorGod.guard();}if(animal instanceof Cat){Cat cat = (Cat)animal;cat.speak();}}

如果没有采取措施(上面使用的措施是instanceof)判断对象的类型,那么向下的强制转换就是不安全的。这种转换错误在编译时是不能检测出来的,只有在运行时才会抛出 ClassCastException异常,对于测试来说,这样的错误也是很难检测的。

6、抽象类的由来----限制基础类只为自己的衍生类提供一个接口,不允许创建一个自己的实例

7、对象的创建和存在时间----对象需要的数据位于哪儿,如何控制对象的“存在时间”呢?

一种是编写程序确定存储及存在时间。如:C++认为程序的执行效率是最重要的一个问题。为获得最快的运行速度,存储以及存在时间可在编写程序时决定。这样便为存储空间的分配和释放提供了一个优先级。这种优先级的控制是非常有价值的。然而,我们同时也牺牲了灵活性,因为在编写程序时,必须知道对象的准确的数量、存在时间、以及类型。

另一种内存池中动态创建对象。若需一个新对象,只需在需要它的时候在内存堆里简单地创建它即可。由于存储空间的管理是运行期间动态进行的,所以在内存堆里分配存储空间的时间比在堆栈里创建的时间长得多(在堆栈里创建存储空间一般只需要一个简单的指令,将堆栈指针向下或向下移动即可)。除此以外,更大的灵活性对于常规编程问题的解决是至关重要的。

程序员可用两种方法来破坏一个对象:用程序化的方式决定何时破坏对象,或者利用由运行环境提供的一种“垃圾收集器”特性,自动寻找那些不再使用的对象,并将其清除。当然,垃圾收集器显得方便得多,但要求所有应用程序都必须容忍垃圾收集器的存在,并能默许随垃圾收集带来的额外开销。

7.1集合与继承器----不知道需要对象个数、存活时间,如何保存呢?

会自动扩充的集合对象,容纳指向其他对象的地址。


最后

持续更新中…

Java编程思想之对象入门相关推荐

  1. JAVA编程思想学习笔记——第一章 对象导论

    搞了一年多java,野路子出身,发现java基础这块还是相当的薄弱!故决定学习<Java编程思想>这本书.在此把学习的知识点记录下! 面向对象的五大特性 1.万物皆为对象 2.程序是对象的 ...

  2. Java编程思想学习(一)----对象导论中多态的理解

    1.1抽象过程 1)万物皆对象. 2)程序是对象的集合,他们通过发送消息来告知彼此所要求做的. 3)每个对象都有自己的由其他对象所构成的存储. 4)每个对象都拥有其类型. 5)某一特定类型的所有对象都 ...

  3. 【Java编程思想】一、对象导论

    Thinking in Java 作为一个电子专业的人,在学习了将近3年的嵌入式技术后,决定投奔移动互联网,在互联网大潮中急流勇进! 为了学习OOP(Object-oriented Programmi ...

  4. 《Java编程思想》学习笔记【一对象导论】

    重头学习Java,大一没怎么学,大二上课也没听.(流下不学无术的眼泪) 所有编程语言都提供抽象机制,我们所能解决的问题的复杂性直接取决于抽象的类型和质量. 汇编语言是对底层机器的轻微抽象," ...

  5. java编程思想怎么样_读完java编程思想后的思考?

    谢邀,这本书真的给我带来很多思考. 我的java入门不是java编程思想,学校的教材是一本紫色的书,已经忘了叫什么名字了,里面内容倒挺新还讲了些javafx.但那本书实在是太浅并且结构混乱,以至于我和 ...

  6. 编程不适合12小时工作制,“我有灵感才工作” | 专访《Java编程思想》作者Bruce Eckel...

    整理 | 蔡芳芳 采访 | 王一鹏.蔡芳芳 本文转载自公众号infoQ 编者按: 如果你是一个 Java 开发者,那你想必读过或至少听过<Java 编程思想>(Thinking in Ja ...

  7. Java编程思想第四版学习总结

    Java编程思想第四版学习总结 文章目录 Java编程思想第四版学习总结 第 1 章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重 ...

  8. 类的包访问权限:《Java编程思想》中一段话的困惑

    类的包访问权限:<Java编程思想>中一段话的困惑 在<java编程思想第三版>(陈昊鹏 饶若楠等译)的第五章隐藏具体实现中,5.4节的最后一段话是: "正如前面所提 ...

  9. 译者招募 | 《Java编程思想》作者Bruce Eckel新作On Java 8

    硅谷创业之父Paul Graham曾在<黑客与画家>中写道,"判断一种语言是否流行的条件是,一种免费的实现,一本相关书籍,以及语言所依附的计算机系统." 当然,Java ...

最新文章

  1. 简单阐述hdfs的体系结构_HDFS主要特性和体系结构
  2. Python机器视觉编程常用数据结构与示例
  3. 如何确定coordinator
  4. 从Hadoop到ClickHouse,现代BI系统有哪些问题?如何解决?
  5. CV新赛事 | 水下鱼类物种识别
  6. 深度学习TF—2.TensorFlow2高阶操作
  7. SQL Server将表数据从一个数据源复制到另一个数据源(未完成)
  8. C语言队列(排队)先进先出.实现全部函数
  9. 记小米公司的一次「测试开发工程师」面试
  10. linux centos7下源码 tar安装mysql5.7.22或mysql5.7.20 图文详解
  11. 教你如何写初/高级前端简历「赠简历导图」
  12. null与undefined的异同点
  13. 【计算机导论调研报告】计算机从业人员的职业道德
  14. 用python输出沙漏_sandglass(沙漏)——一个让人解脱的python时间处理库
  15. (整理)手机上一些常用的url
  16. oracle ins ctx.mk,(原创)RHEL/CentOS 6.x 64位安装Oracle11gR2 64位出现ins_ctx.mk报错解决...
  17. 推荐10个在线logo设计网站
  18. CUDA编程学习0——环境搭建环境详解
  19. Ele睡眠面膜,祛痘、去痘印、美白功效
  20. 全栈开发之前端开发-欧阳桫-专题视频课程

热门文章

  1. ​计算机视觉传感器系统
  2. C 语言究竟能干什么
  3. DES的加密解密在ECB上的使用(C语言实现)——大三密码学实验
  4. 社区o2o怎么做线上推广?
  5. excel数字点一下才变为数值的批量快捷操作
  6. 求图形的周长和面积java_抽象类求图形周长和面积
  7. C++ | 数据结构 | 图结构的讲解与模拟实现 | DFS与BFS的实现
  8. Html5 学习笔记 【PC固定布局】 实战6 咨询页面
  9. 开关电源常用保护电路-过热、过流、过压以及软启动保护电路
  10. python 股票交易接口 github_GitHub - zhaoneng/vnpy: 基于python的开源交易平台开发框架...