--------android培训、java培训、期待与您交流! ----------

面向对象总结2

一:引用变量的强制类型转换

在Java中,人们常常提到引用类型的变量,其实质引用变量只能调用它在编译时类型的方法,而不能调用它运行时类型的方法,即使它实际所引用对象确实包括该方法。如果需要让这个引用变量来调用它运行时类型的方法,则必须把它强制类型转换成运行时类型。
格式:类型转换运算符是小括号,如(type)variable    将variable变量转换为一个type类型的变量。
eg   Object obj="java" ;    String objStr=(String)obj;
强制类型转换时需要注意一下几点:
(1)基本类型之间的转换只能在数值类型(整数类型,字符型和浮点型)之间进行,注意,数值型不能和布尔类型之间进行转换。
(2)引用类型之间的转换只能把一个父类型变量转换成子类型(简单的说就是父类引用指向子类对象,被称为向上转型)。
instanceof运算符:instanceof运算符的前一个操作数是一个引用类型的变量,后一个操作数通常是一个类,也可以是一个接口,它用于判断前面的对象是否是后面对象的类,或者其子类,实现类的实例。如果是,则返回true,否则返回false。

实例:

public static void main(String[] args) {  //定义一个Object类的变量  Object obj="heima";  //返回true  System.out.println("字符串是否是Object类的实例:"+(obj instanceof Object));  //String是Object类的子类,所以返回true  System.out.println("字符串是否是String类的实例:"+(obj instanceof String));  //Math是Object类的子类,所以能正常编译。所以返回false  System.out.println("字符串是否是Math类的实例:"+(obj instanceof Math));  //String实现了Comparable接口,所以返回true  System.out.println("字符串是否是Comparable接口的实例:"+(obj instanceof Comparable));  String str="java";  //String类不是Math类,也不是Math类的父类,所以下面的代码不能进行编译  System.out.println("字符串是否是Math类的实例:"+(str instanceof Math));  }  

Instanceof和(type)是Java提供的两个相关的运算符,一般先用instanceof判断一个对象是否可以强制类型转换,然后再使用(type)运算符进行强制类型转换,从而保证程序不会出现错误。

二:初始化块

初始化块分为:静态初始化块(在大括号前使用static修饰)和普通初始化块。
初始化块的作用和构造器非常类型,主要用于初始化。
初始化块格式: 
[修饰符]{
初始化块的可执行代码[包含任何可执行性语句,包括定义局部变量,调用其他对象的方法,使用分支语句和循环语句等等]

虽然Java中允许在类中定义多个初始化块,但这没太多的意义,因为初始化块是在创建Java对象时隐式执行的,而且总是全部执行,因此当我们完全可以把多个普通初始化块合并成一个初始化块。这样可以挺高程序的可读性。
注意:初始化块,声明实例属性指定默认值都可认为是对象的初始化代码,他们的执行顺序与源代码中的顺序相同。

实例:

public class Test {  //先执行初始化块,给变量num赋值为10  {  num=10;  }  //在执行将变量a的值赋值为6  int num=6;  public static void main(String[] args) {  //下面打印的结果是:变量num=6  System.out.println("变量num="+new Test().num);  }
}  

上面的实例充分说明他们的执行顺序与源代码中的顺序相同。
当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序 开始对这个实例属性执行初始化,其顺序是:先执行初始化块或者声明属性时指定的初始值,再执行构造器里指定的初始值。通过其他命令可以解析Java执行的源码,其实质是,程序在执行初始化时,会将初始化块中的代码和声明属性的代码都移植到构造函数中,这些代码都位于构造函数自身代码之前。所以他们总是比构造函数自身代码先执行。

静态初始化块:

定义初始化块时使用static修饰符,叫做静态初始化块。静态初始化块与类相关,所以系统将在类初始化阶段执行静态初始化块,因此静态初始化块总是比普通初始化块先执行。静态初始化块属于类的静态成员,同样需要遵循静态成员不能访问非静态成员的规则,因此静态初始化块不能访问非静态成员,包括不能访问实例属性和方法。
初始化块与构造函数类似,创建一个Java对象时,不仅会执行该类的普通初始化和构造器,系统会一直追溯到java.lang.Object类,先执行java.lang.Object类的初始化块,开始执行Object的构造函数,依次向下执行其父类的初始化块,和构造函数.......。最后才能执行自身的初始化块和构造函数。

实例:

public class Test extends Root {  static{  System.out.println("我是Test的静态初始化块");  }  {  System.out.println("我是Test的普通初始化块");  }  public Test() {  System.out.println("我是Test的构造函数");  }  public Test(String msg){  System.out.println(msg);  }
}
class Test2 extends Root{  static{  System.out.println("我是Test2的静态初始化块");  }  {  System.out.println("我是Test2的普通初始化块");  }  public Test2() {  System.out.println("我是Test2的构造函数");  }  public static void main(String[] args) {  new Test2();  new Test2();  }
}
class Root{  static{  System.out.println("我是Root的静态初始化块");  }  {  System.out.println("我是Root的普通初始化块");  }  public Root() {  System.out.println("我是Root的构造函数");  }
}  

打印结果:
我是Root的静态初始化块
我是Test2的静态初始化块
我是Root的普通初始化块
我是Root的构造函数
我是Test2的普通初始化块
我是Test2的构造函数
我是Root的普通初始化块
我是Root的构造函数
我是Test2的普通初始化块
我是Test2的构造函数

三:"=="和equals比较运算符

Java程序中判断两个变量是否相等有两种方式:一种是利用==运算符,一种是利用equals方法。

当使用==来判断两个变量是否相等时,如果2个变量是基本类型的变量,且都是数值型(不一定要求数据类型严格相同),则只要两个变量的值相等,这返回true。但对于两个引用类型的变量,必须他们指向同一个对象时,==判断才会返回true。
equals方法是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法来判断是否与其他引用变量相等。但这个判断是两个对象相等的标准与==符号没有区别,同样要求两个应用变量来指向同一个对象才会返回true。因此这个Object提供的equals方法没有太大的实际意义,如果希望采用自定义的相等标准,可以采用重写equals方法来实现【实际上,重新equals方法就是提供自定义相等的标准,你认为怎么样相等,就怎么样相等。一切都是你做主】。

实例一:

public static void main(String[] args) {  int num=65;  float fnum=65.0f;  char ch='A';  System.out.println("65和65.0f是否相等:"+(num==fnum));//true  System.out.println("65和'A'是否相等:"+(num==ch));//true  String str1=new String("ABC");  String str2=new String("ABC");  System.out.println("str1和str2是否相等="+(str1==str2));//false  //String类已经重新了equals方法,String的equals方法判断两个字符串是否相等的  //标准是:只要两个字符串包含的字符序列相同,就返回true,否则返回false。  System.out.println("str1和str2是否相等="+(str1.equals(str2)));//true  }  

实例二:

public class Test1 {  private String idCard;  public String getIdCard() {  return idCard;  }  public void setIdCard(String idCard) {  this.idCard = idCard;  }  //重写equals方法  public boolean equals(Object obj) {  //比较的两个对象是否是同一对象  if (this == obj) {  return true;  }  //只有当obj是Test1对象  if (obj != null && obj.getClass() == Test1.class) {  Test1 test = (Test1) obj;  if (this.getIdCard().equals(test.getIdCard())) {  return true;  }  }  return false;  }
}  

四:final修饰符

final关键字可用于修饰类,变量和方法,被final修饰的类,方法和变量是不可变的。
final修饰变量,被修饰的变量被赋初始值之后,不能对它重新赋值。final修饰方法,被final修饰的方法不能被重写。final修饰类,被final修饰的类不能派生子类。
final修饰实例变量可以在三个位置指定初始值:
(1)在定义final实例变量时指定初始值。
(2)在非静态初始化块中为final实例变量指定初始值。
(3)在构造器中为final实例变量指定初始值。
对于普通的实例变量,Java程序可以对它执行默认的初始化,也就是将实例变量的值指定为默认的初始值0或null;但对于final实例变量,则必须由程序员显示指定初始值。
final修饰类变量可以在两个地方指定初始值
(1)定义final类变量时指定初始值。
(2)在静态初始化块中为final类变量指定初始值。
除上面两个地方可以为final类变量指定初始值外,final类变量不能再次赋值。
final修饰局部变量:
Java本来就要求局部变量必须被显式的赋初始值,final修饰的局部变量一样需要被显式的赋初始值。与普通初始值变量不同的是,final修饰的局部变量被赋初始值之后,就不能再对final局部变量重新赋值。
对于一个使用final修饰的变量(类变量,实例变量,局部变量)而言,如果定义该final变量时就指定初始值或确定的表达式(如果被赋的表达式只是基本的算术运算表达式或字符串连接运算,没有访问普通变量,调用方法),而且这个初始值可以在编译时就确定下来,那么这个final变量将不再是一个变量,系统会将其当成"宏变量"处理。也就是说,所有出现该变量的地方,系统将直接把它当成对应的值处理。
实例:

public static void main(String[] args) {  //下面定义五个宏变量。  final int a=5;  final int b=5+3;  final  double c=1.2/3;  final String str1="Java"+" Android";  final String str2="Java"+99;  //str3变量的值因为调用了方法,所以在编译时不能确定值,因此str3不是宏变量。  final String str3="Java"+String.valueOf(99);  System.out.println(str2=="Java99");//返回true  System.out.println(str3=="Java99");//返回false  }

Java要求所有被内部类访问的局部变量都使用final修饰,对应普通局部变量而言,它的作用域就是停留在该方法内,当方法执行结束,该局部变量也随之消失;但内部类则可能产生隐式的“闭包”,闭包将使得局部变量脱离它所在的方法继续存在【此处说的内部类指的是局部内部类,因为只有局部内部类(包括匿名内部类)才可以访问局部变量,普通静态内部类,非静态内部类不可访问方法体的局部变量】。

五:抽象类和抽象方法
在Java中被abstract修饰的类,叫抽象类,被abstract修饰的方法,叫抽象方法。
抽象类和抽象方法原则:
(1)抽象类必须使用abstract修饰符修饰,抽象方法必须使用abstract修饰符修饰,抽象方法不能有方法体。
(2)抽象类不能被实例化,即使抽象类中不包含抽象方法,同样也不能创建实例。
(3)抽象类可以包含属性,方法(普通方法和抽象方法都可以),构造器,初始化块,内部类,枚举类六种成分。抽象类的构造器不能用于创建实例,主要是用于被子类调用。
(4)含有抽象方法的类,只能被定义为抽象类。

注意:
(1)抽象方法和空方法体的方法是不同概念,例如public abstract void test();是一个抽象方法,它根本没有方法体,方法后面没有大括号,但public void test(){}方法是一个普通的方法,他已经定义了方法体,只是方法体是空,因此该方法不能用abstract修饰。
(2)abstract不能用于修饰属性,不能用于修饰局部变量,即使没有抽象变量,没有抽象属性等说法;abstract也不能修饰构造器,没有抽象构造器。抽象类中定义的构造器只能是普通的构造器。
(3)当使用static修饰一个方法时,该方法属于类,如果该方法被定义成抽象方法,则将导致通过该类来调用该方法时出现错误,因此static和abstract不能同时修饰某个方法。
(4)abstract关键字修饰的方法必须被子类重写才有意义,因此abstract方法不能定义为private访问权限。

抽象类的作用:
抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模版,从而避免子类设计的随意性。抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展,改造,但子类总体上会大致保留抽象类的行为方式。

六:接口
接口是从多个相似类中抽象出来的规范,接口不提供任何实现。可以看成是抽象类的一种特殊。
由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义,接口里可以包含属性(只能是常量,默认是public static final,只能是public static final)、方法(只能是抽象方法,默认修饰符是public,也只能是public)、内部类(包括内部接口)和枚举定义。

接口支持多继承,一个接口可以有多个直接的父接口。和类的继承相似,子接口可以扩展某个父接口,将会获得父接口里所有的抽象方法,常量属性,内部类和枚举类的定义。格式: interface D extends A,B,C{ }

注意:
(1)接口不能创建实例,但接口可以用于声明引用类型的变量。当使用接口来声明引用类型的变量时,这个引用类型的变量必须引用到其实现类的对象。
(2)一个类可以实现一个和多个接口,多个接口之间使用逗号隔开。

总结接口和抽象类:
相同特点:
(1)接口和抽象类都不能实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
(2)接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通之类都必须实现这些抽象方法。
不同特点:
(1)二者的设计目的不同,接口作为系统与外界交换的窗口,接口体现的是一种规范。从某种程度上看,接口类似于整个系统的"总纲",他制定了系统各模块应该遵循的标准,因此一个系统中的接口不应该经常修改,一定接口被修改,对整个系统甚至其他系统的影响都非常大(导致大部分类都需要修改)。抽象类就不一样,抽象类作为系统中多个子类的共同父类,它所体现的是一种模板式的设计,抽象类作为多个子类的抽象父类,可以被当成系统实现过程中的中间产品,这个中间产品已经实现了系统的大部分功能,但这个产品不是最终产品,必须进一步完善。
(2)接口里只能包括抽象方法,不能包含已经提供实现的方法 ;抽象类则可以包含已经实现的方法。
(3)接口里不能定义静态方法;抽象类可以定义静态方法。
(4)接口里只能定义静态常量属性,不能定义普通属性;抽象类里既可以定义普通属性,也可以定义静态常量属性。
(5)接口不包含构造器;抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让子类调用这个构造器来完成属与抽象类的初始化操作。
(6)接口里不能包含初始化块,但抽象类则完全可以包含初始化块。

(7)一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java中的单继承。

--------android培训、java培训、期待与您交流! ----------

黑马程序员 面向对象总结2相关推荐

  1. 黑马程序员——面向对象(1)

    ------ Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 三.黑马程序员-面向对象(1) 面向对象(Object-Oriented,简称OO)就是一种常 ...

  2. 黑马程序员 面向对象总结1

    --------android培训.java培训.期待与您交流! ---------- 面向对象总结1 一:类,对象,属性,方法,构造器的概念: 类:用于描述客观世界里某一类对象的共同特征. 对象:可 ...

  3. 黑马程序员---面向对象上(封装,继承,多态)

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

  4. 黑马程序员—面向对象(1)

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

  5. 黑马程序员 面向对象

    --------------android培训.Java培训.学习型技术博客.期待与您交流! -------------- 特点:1:将复杂的事情简单化. 2:面向对象将以前的过程中的执行者,变成了指 ...

  6. 黑马程序员-面向对象-06天-5(单例设计模式)

    package java06;/** 设计模式:解决某一类问题最行之有效的方法.* java中23种设计模式:* 单例设计模式:解决一个类在内存只存在一个对象.* 想要保证对象唯一.* 1,为了避免其 ...

  7. 黑马程序员---面向对象笔记总结

    ------- android培训.java培训.期待与您交流! ---------- 封装 匿名函数 2--匿名对象使用方式一,当对象的方法只调用一次时,可以用匿名对象完成,这样写比较简单,如果对一 ...

  8. 黑马程序员-面向对象-08天-2 (多态)

    package java08;/** 多态:可以理解为事物存在的多种体现形态.*人:男人,女人*动物:猫,狗.*猫 x = new 猫();*动物 x = new 猫();*1,多态的体现* 父类的引 ...

  9. 黑马程序员-面向对象-06天-3(static-静态代码块)

    package java06;/** 静态代码块.* 格式:* static* {* 静态代码块中的执行语句.* } * 特点:随着类的加载而执行,只执行一次,并优先于主函数.* 用于给类进行初始化的 ...

最新文章

  1. BeanShell变量的基本范围
  2. 记事本写python怎么运行-python入门之一个简单记事本
  3. Java黑皮书课后题第4章:*4.8(给出ASCII码对应的字符)编写程序,得到一个ASCII码的输入(0~27之间的一个整数),然后显示该字符
  4. 使用VMware VSphere WebService SDK进行开发 (二)——获取虚拟机cpu的使用情况
  5. SAP Fiori footer的重写方式
  6. python类型提示模块包_Python checktypes包_程序模块 - PyPI - Python中文网
  7. 计算机组成原理-复习题2
  8. Hbuilder X 开发APP指南
  9. 联想主板9针开关接线图_干货丨34个电气控制接线图、电子元件工作原理图
  10. 正弦信号与噪声信号仿真生成实测信号,自相关分析
  11. 优酷发布2018世界杯战略 视频云将提供全程技术保障
  12. jdk1.8中的永久代和元空间
  13. UOJ #60. 【UR #5】怎样提高智商
  14. [Simulink] 从手写代码到自动生成代码
  15. 2020年 交通领域SCI期刊分区
  16. 给加西亚的信》--如何做一名优秀员工
  17. JSP页面分页显示数据
  18. 财务系统数字转化方法
  19. 怎样用键盘控制电脑的光标
  20. 智能手持终端CPU选型报告

热门文章

  1. 《游戏学习》| 微信蜘蛛侠动作游戏源码分析
  2. Hello 微信小程序
  3. postfix无法发送邮件问题
  4. Q妹教你赚外快:如何把微信聊天记录写入文件
  5. 解决CPU风扇噪音故障
  6. idea 导入 vue项目 improt全都报红
  7. STL的allocaotr
  8. sessionStorage储存对象的方式
  9. 从JDBC到Mybatis以及IDEA通过mybatis开发Springboot
  10. 当运行npm install 命令的时候带上ignore-scripts,会发生什么?