第五章 面向对象(上)
这是阅读李刚《疯狂Java讲义》后记录的关键知识。用于补充自己的知识盲区,所以并不会面面俱到。
1.在学习继承的时候了解到了一个新的概念:组合。组合和继承都是了代码的复用,不过组合需要构造更多对象,代码量更大。它的优势是降低了代码的耦合性,在软件维护阶段优势更突出。到底是该用组合还是继承,一个最清晰的判断方法就是问一问自己是否需要从新类向基类进行向上转型,需要的话就用继承,不需要的话就用组合方式。(后面有继承和组合的代码对比)
2.static修饰的成员不能访问不带static修饰地成员
this关键字作为对象默认引用地两种情形:
- 构造器中引用该构造器正在初始化的方法
- 在方法中引用调用该方法的对象 (this可省略)
static修饰的方法中不能使用this关键字
不要使用对象去调用static方法,应该使用类去调用。
3.java参数传递机制:值传递。例:swap函数,在Java中用数组实现或者新构造一个类,调用类的参数来实现,不能像c一样直接实现。
4.形参个数可变的方法
public static void test(int a,String... books){
}
//或者 以数组形式
publi static void test(int a,String[] books){
}
//调用方法也不一样
1. test(5,"数据结构","计算机网络")
2. tset(5,new String[]{"数据结构","计算机网络"})
5.方法在重载时不能依据方法的返回类型来判断,应该依据参数列表。
6.当父包中的类想要使用子包的类时,必须使用子包的完整包路径加类名。
7.当引入的两个类中都含有想引用的方法时必须写出该类的全名
import java.util*/;
import java.sql*/;
java.sql.Date d=new java.sql.Date();
8.java常用包
- java.lang:包含核心类,如: String、Math、System、Thread (无需用import引入,系统自动引入)
- java.util:包含工具类/接口和集合框架类/接口 Arrays、List、Set
- java.net:网络编程相关
- java.io:输入输出相关
9.一个构造器调用另一个构造器的例子
public class Apple{
public String name;
public String color;
public double weight;
public Apple(){}
public Apple(String name,String color){
this.name=name;
this.color=color;
}
public Apple(String name,String color,double weight){
this(name,color); //只能作为第一条语句 使用this在后期维护更新时减少麻烦
this.weight=weight;
}
}
10.重载适用于方法,改变同一方法形参;重写适用于父子类之间,子类改变父类的方法。
重写遵守“两同两小一大”。
- 两同:方法名相同,形参列表相同
- 两小:子类方法返回值类型小于或等于父类,子类方法抛出的异常小于等于父类
- 一大:子类方法访问的权限应大于等于父类
当子类的方法名与父类的方法名相同时,父类的方法被“隐藏”,只能用super来调用
super不能出现在被static修饰的类里。
向上转型实例:
class Parent{
public String tag="数据结构";
}
class Derived extends Parent{
private String tag="计算机网络";
}
public class HideTest{
public void static main(String[] args){
var d=new Derived();
//Dervide的tag是私有的 不能访问,只能向上转型访问Parent的
System.out.println(((Parent) d).tag);
}
}
11.多态:编译时类型和运行时类型不一致。
编译时 是BaseClass ,运行时则是SubClass。
调用子类和父类都有的方法时,会调用子类覆盖的方法。
若调用子类有而父类没有的方法时则会报错,因为没有完成编译。
对象的实例变量不会发生多态,只有方法能。会输出编译时(即父类)的变量。
强制转换类型时,两个类型之间需要存在继承关系
强制转换,精度高的范围广的转换为精度低的范围小的。
可用instanceof在判断是否可以转换成功,来增强程序的健壮性。
if (int instanceof String){
var str=(String) int;
}
将子类的对象给父类引用变量时叫“向上转型”。
12.继承与复用的对比
//继承
class Animal{
public void beat(){
System.out.println("心脏跳动...")
}
public void breathe(){
System.out.printlin("呼吸...")
}
}
class Bird extends Animal{
public void fly(){
System.out.println("起飞,唉,起飞")
}
}
class Wolf extends Animal{
public void run(){
System.out.println("溜了溜了...")
}
}
public class Test1{
public static void main (String[] args){
var b=new Bird();
b.breathe();
b.fly();
var w=new Wolf();
w.breathe();
w.run();
}
}
//组合
class Animal{
public void beat(){
System.out.println("心脏跳动...")
}
public void breathe(){
System.out.printlin("呼吸...")
}
}
class Bird {
public Bird(Animal a){
this.a=a;
}
public void breathe(){
a.breathe();
}
public void fly(){
System.out.println("起飞,唉,起飞")
}
}
class Wolf {
public Wolf(Animal a){
this.a=a;
}
public void breathe(){
a.breathe();
}
public void run(){
System.out.println("溜了溜了...")
}
}
public class Test2{
public static void main (String[] args){
var a1=new Animal();
var b=new Bird(al);
b.breathe();
b.fly();
var a2=new Animal();
var w=new Wolf(a2);
w.breathe();
w.run();
}
}
13.static 修饰的代码块永远最先执行,顺序是顶层父类——>父类——>子类;然后执行实例代码块和构造器,顺序是顶层父类——>父类——>子类。