java总结:面向对象

摘自廖雪峰java教程

参数绑定
  • 基本类型参数的传递,是调用方值的复制。双方各自的后续修改,互不影响
  • 引用类型参数的传递,调用方的变量,和接收方的参数变量,指向的是同一个对象。双方任意一方对这个对象的修改,都会影响对方

因此在类的方法中传参时要注意引用类型的变量的使用,在传入一个string后在类外面给string重新赋值会使字符串指向新地址,因此类中的string不会受影响

构造方法
  • 如果我们自定义了一个构造方法,那么,编译器就不再自动创建默认构造方法
  • 没有在构造方法中初始化字段时,引用类型的字段默认是null,数值类型的字段用默认值,int类型默认值是0,布尔类型默认值是false
  • 一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。调用其他构造方法的语法是this(其他构造方法的参数)
重载
  • 方法名相同,但各自的参数不同,称为方法重载(Overload)
继承
  • 子类自动获得了父类的所有字段,严禁定义与父类重名的字段
  • 在Java中,没有明确写extends的类,编译器会自动加上extends Object
  • 如果父类没有默认的构造方法,子类构造函数的第一句必须显式调用super()并给出参数以便让编译器定位到父类的一个合适的构造方法。
  • 子类不会继承任何父类的构造方法。子类默认的构造方法是编译器自动生成的,不是继承的
向上转型

把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)

向下转型
  • 如果一个父类变量是用子类的构造函数初始化的则能转型,否则不成功
  • 因此转型前应先用 instanceof instanceof 判断,如果一个引用变量为null,那么对任何instanceof的判断都为false

代码

Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型:
    Student s = (Student) p; // 一定会成功
}
继承与组合
  • 继承是is关系,组合是has关系
  • 组合即持有另一个类的实例作为成员变量
多态
  • 在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)
  • Override和Overload不同的是,如果方法签名如果不同,就是Overload,Overload方法是一个新方法;如果方法签名相同,并且返回值也相同,就是Override
  • 方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。在Java程序中,出现这种情况,编译器会报错
  • 多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法
  • 多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码
  • Object定义了几个重要的方法:toString(),equals(),hashCode()
  • 在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用
  • 如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为final。用final修饰的方法不能被Override
  • 如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为final。用final修饰的类不能被继承
  • 对于一个类的实例字段,同样可以用final修饰。用final修饰的字段在初始化后不能被修改,可以在构造方法中初始化final字段
抽象类
  • 如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。
  • 因为无法执行抽象方法,因此这个类也必须申明为抽象类(abstract class)。
  • 使用abstract修饰的类就是抽象类。我们无法实例化一个抽象类
  • 抽象类可以强迫子类实现其定义的抽象方法,相当于定义了“规范”
  • 可以通过抽象类去引用具体的子类的实例,这种引用抽象类的好处在于,我们对其进行方法调用,并不关心Person类型变量的具体子类型,这种尽量引用高层类型,避免引用实际子类型的方式,称之为面向抽象编程
  • 面向抽象编程的本质就是:
    • 上层代码只定义规范
    • 不需要子类就可以实现业务逻辑(正常编译)
    • 具体的业务逻辑由不同的子类实现,调用者并不关心
接口
  • 如果一个抽象类没有字段,所有方法全部都是抽象方法,就可以把该抽象类改写为接口:interface
  • 接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要写出来
  • 当一个具体的class去实现一个interface时,需要使用implements关键字
  • 一个类可以实现多个interface
  • 一个interface可以继承自另一个interface。interface继承自interface使用extends
  • 实现类可以不必覆写default方法。default方法的目的是,当我们需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。
  • default方法和抽象类的普通方法是有所不同的。因为interface没有字段,default方法无法访问字段,而抽象类的普通方法可以访问实例字段。
  • 合理设计interface和abstract class的继承关系,可以充分复用代码。一般来说,公共逻辑适合放在abstract class中,具体逻辑放到各个子类,而接口层次代表抽象程度
  • 在使用的时候,实例化的对象永远只能是某个具体的子类,但总是通过接口去引用它,因为接口比抽象类更抽象
静态字段和方法
  • 对于静态字段,无论修改哪个实例的静态字段,效果都是一样的:所有实例的静态字段都被修改了,原因是静态字段并不属于实例
  • 推荐用类名来访问静态字段
  • 静态方法内部,无法访问this变量,也无法访问实例字段,它只能访问静态字段
  • 静态方法经常用于工具类。例如:Arrays.sort(),Math.random()
  • 因为interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且静态字段必须为final类型
public interface Person {
    public static final int MALE = 1;
    int FEMALE = 2;
}
  • 在定义class的时候,我们需要在第一行声明这个class属于哪个包

  • 包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系

  • 位于同一个包的类,可以访问包作用域的字段和方法。不用public、protected、private修饰的字段和方法就是包作用域

  • import时一般导入完整类名

  • 在写import的时候,可以使用*,表示把这个包下面的所有class都导入进来(但不包括子包的class)

  • Java编译器最终编译出的.class文件只使用完整类名,因此,在代码中,当编译器遇到一个class名称时:

    • 如果是完整类名,就直接根据完整类名查找这个class;
    • 如果是简单类名,按下面的顺序依次查找:
      • 查找当前package是否存在这个class;
      • 查找import的包是否包含这个class;
      • 查找java.lang包是否包含这个class。

    如果按照上面的规则还无法确定类名,则编译报错。

  • 推荐的做法是使用倒置的域名来确保唯一性

  • 要注意不要和java.lang包的类重名,也不要和JDK常用类重名

作用域
  • 推荐把private方法放到后面,因为public方法定义了类对外提供的功能,阅读代码的时候,应该先关注public方法
  • 由于Java支持嵌套类,如果一个类内部还定义了嵌套类,那么,嵌套类拥有访问private的权限
  • 用final修饰局部变量可以阻止被重新赋值
  • 如果不确定是否需要public,就不声明为public,即尽可能少地暴露对外的字段和方法。
  • 把方法定义为package权限有助于测试,因为测试类和被测试类只要位于同一个package,测试代码就可以访问被测试类的package权限方法。
  • 一个.java文件只能包含一个public类,但可以包含多个非public类。如果有public类,文件名必须和public类的名字相同
classpath
  • classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索class

  • 假设classpath是.;C:\work\project1\bin;C:\shared,当JVM在加载abc.xyz.Hello这个类时,会依次查找:

    • <当前目录>\abc\xyz\Hello.class
    • C:\work\project1\bin\abc\xyz\Hello.class
    • C:\shared\abc\xyz\Hello.class
  • 强烈不推荐在系统环境变量中设置classpath,那样会污染整个系统环境。在启动JVM时设置classpath才是推荐的做法。实际上就是给java命令传入-classpath或-cp参数

    java -classpath .;C:\work\project1\bin;C:\shared abc.xyz.Hello

  • 在IDE中运行Java程序,IDE自动传入的-cp参数是当前工程的bin目录和引入的jar包

  • 没有设置系统环境变量,也没有传入-cp参数,那么JVM默认的classpath为.,即当前目录,更好的做法是,不要设置classpath!默认的当前目录.对于绝大多数情况都够用了

jar
  • 因为jar包就是zip包,所以,直接在资源管理器中,找到正确的目录,点击右键,在弹出的快捷菜单中选择“发送到”,“压缩(zipped)文件夹”,就制作了一个zip文件。然后,把后缀从.zip改为.jar,一个jar包就创建成功其余见教程
  • 其余见教程
模块
  • jar只是用于存放class的容器,它并不关心class之间的依赖
  • 从Java 9开始引入的模块,主要是为了解决“依赖”这个问题。如果a.jar必须依赖另一个b.jar才能运行,那我们应该给a.jar加点说明啥的,让程序在编译和运行的时候能自动定位到b.jar,这种自带“依赖关系”的class容器就是模块
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值