第二周 面向对象
2019.8.5
类
-
包含属性(准确说是field 域)、方法、构造方法、代码块、内部类/接口...
-
实例 instance,访问access
-
类的实例化:分配内存空间, new Constructor();初始化对象属性,读取初始化数据
-
一个Java文件可以有一个或多个类,最多只有一个public类
-
类只能用public 和默认访问修饰,内部类可以用private protected
-
使用Field遍历对象
//学生类 public class Student { public String name; public int age; } Student stu=new Student(); Field[] field=stu.getClass().getDeclaredFields();//获取stu所有属性,getFields()获取public属性 for(Field f:fields) { f.setAccessible(true);//设置私有属性可访问 System.out.print(f.getName()+f.get(stud));//输出属性及其名称 }
-
如果属性没有显式赋值,则有默认值,默认构造方法会赋默认值:数值型0、false。。。
-
访问属性或者方法之前,对象不能为null
-
方法:
-
方法参数需要进行有效性校验
-
减少代码,提高维护性
-
采用文档注释:/**+enter
-
-
数组传参的时候
isEquals(new int[]{1,2,3},new int[]{1,23,4});//可以新建数组 isEquals({1,23,4},{123,35});//不行!XXXX
-
如果是基本类型,传值;引用类型,传地址;String为不可变,会重新创建内存空间
-
可变长度参数,int... nums,可变长度参数最多一个,只能出现在最后一个参数
public void abc(int num1,int... nums)//位置只能放最后 { }
-
添加对象数组时,主要新建对象,不然会改变原值
2019.8.6
-
包
- 作用:组织管理代码,避免命名冲突,控制访问范围
- 域名反写,包与文件系统一一对应
- JDK的包:
- java.io:处理IO,nio非阻塞IO
- java.lang: 基础类,不需要引用
- java.math
- java.net: 网络编程
- java.sql: 关系数据库
- java.time: 日期时间操作
- java.util: 集合框架 工具类
- import package.class;
-
ctrl+shift+o:优化导入,导入不识别的类,移除未使用导入类,按一定规则排序导入语句
-
访问修饰符
-
private: 类内部使用
-
default: 没有关键字 本包内可以访问
-
protected: 受保护的,修饰方法、属性、内部类,能在本包内访问,且可以被子类访问(子类可以在不同包)
public class SuperClass{protected int a}
public class SubClass extends SuperClasee{}
// 包2中
public class Test(){
main(){
SubClass child=new SubClass();
//访问不到child.a
}
}+ public: 公共 + 设计原则:从最严格控制访问private,然后使用访问控制更大的关键字 + 实际开发:大多类为public 方法大多public + 目前:属性使用private,使用public的getter,setter,里面可以设置控制输入
-
-
属性规范
/** * 反例 */ int a;// 不要使用一个字母,xxxxxxxx String uName;// 不要使用只有一个小写字母开头的属性
- 建议:
- 名词
- 至少开头的两个小写字母
- 多个单词,第二个单词开始首字母大写
- 建议:
-
static:
-
不能在局部声明
-
修饰属性,类的成员,所有实例共享该属性,无需实例化,直接使用 类名.属性
-
修饰方法,
-
载入类的时候会初始化类中所有静态属性
-
静态导入
import static package.class.staticMethod staticMethod();//导入后直接使用,不用加类名
-
-
F3 查看源码,或者Ctrl+单击
-
构造方法:
- 与类名相同 ,没有 返回值类型
- 无显式构造方法,编译器会创建无参默认构造方法,访问控制符与类一致
- 初始化实例
- 用new 使用或者super
设计模式
Design Pattern 2019.8.7
-
单例模式(Singleton)
-
只能创建一个实例
-
类内创建,static 方法创建
-
作用:
- 保证系统中只有一个实例(不包括分布式系统)
-
实现方式:构造方法私有化
- 懒汉式:在第一次 获取实例 时才实例化,注意线程安全
- 饿汉式:第一次使用该类时,就会实例化,线程安全,性能稍差
//单机管用 // 懒汉模式 线程不安全 public Singleton() { private Singleton() { } private Singleton singleton; public static int num=0; public static Singleton getInstance() { if(singleton==null)// 判断后,其他线程进入,会不安全,可能会创建一个新的single { singleton=new Singleton(); } return singleton; } } // 饥汉模式 必须创建实例 //加载类的时候救火初始化所有静态变量 实例也被初始化 public class Single2{ priavte Single2() { // } public static int num=0; private static final Singleton2 single=new Singleton(); public static Singleton2 getInstance() { return single; } }
-
封装
-
将内部细节封装起来。提供一些公共接口供外部访问
-
文章:你的java安全吗 IBM
包装类
-
int Integer
-
long Long
-
char Character
- byte Byte
- boolean Boolean
- short Short
- double Double
思路:封装提供方法
- 自动装箱 (java 1.5之后):基本数据类型——>包装类,Integer i2=200;将200转为Integer
- 自动拆箱:包装类——>基本类型,int num=i2;i2转为num
Integer i2=200;//将200转为Integer,自动装箱
int num=i2;//i2转为num,自动拆箱
Integer i3=200;
i2==i3;//false
//如果i2,i3在一个Byte -128到127之间为true
- 如果Integer类型的i2,i3,i2==i3在一个Byte -128到127之间为true,常量区缓存
重载(overload)
-
方法参数个数、类型,参数不同类型的顺序 不同
-
实参会自动转换,优先匹配不用转换的,先找基本类型,按照范围依次调用,再找包装类型,否则继续找包装类的父类型Object
public void m1(int num){} public void m1(float num){} public void m1(double num){} public void m1(Integer num){} public void m1(Object num){} m1(1);//先找int,然后float,double,再Integer,最后Object
this
-
当前实例
-
不能用于静态作用域(方法、代码块)
-
用于构造方法,可以访问该类其他的 承载构造方法 this(参数),必须出现在第一行
public ThisDemo() { this(1,2);// 只能第一句 } public ThisDemo(int num1) { this(num,2);// 只能第一句 } public ThisDemo(int num1,int num2) { this.num1=num1; this.num2=num2; }
Eclipse:
- Ctrl +W 关闭文件
- Ctrl + Shift+T 搜索类,查看源码,CTRL+单击查看源码
继承
2018.8.8
-
关键字 extends
-
父类中被子类继承:public,protected
-
不能被继承:private,default,构造方法
-
单继承
-
instanceof 关键字:
-
二元运算符 左边对象,右边是类;对象是否为该类
-
实例包含类本身的实例,以及所有直接或间接子类实例
-
左边显式声明的类型与右边操作元必须是同种类或存在继承关系,
也就是说需要位于同一个继承树,否则会编译错误
-
使用该运算符的场景大部分情况是为了后续的向下转型,或称为保证类型安全
-
-
子类转父类不会丢失,只是指针类型变了,地址还是同一块,内容不会丢失
public class Shape{} public class Square extends Shape{} Shape shape=new Square();// shape实例是一个square类型 // 只能调到Shape的方法,会调用子类重写方法 // list是个接口,按照arraylist分配空间创建实例 List<User> user=new ArrayList<User>(); //通过接口统一子类行为,限制子类扩展一下不当行为
绑定
-
new 的什么类型就调哪个的函数
-
向上转型:子类向父类转换,自动
-
向下转型:父类型——>子类型,语法(subClass)
-
静态(前期):编译时就能决定属性和方法,static修饰的成员或方法
-
动态:运行时才能决定访问到谁的属性,new的什么类型就调什么类型的方法;
List list= new ArrayList();
找左边类型的方法(list的方法),运行时才调用子方法(arraylist的方法);
重写 (覆盖) override
- 子类重新实现父类方法,方法名、参数例表一样
- 返回类型要兼容(相同,或者 父类方法返回值 的子类)
- 子类方法的访问控制修饰符,范围不能缩小
- 子类方法声明抛出的异常,不能比父类方法声明抛出的异常多
- 注解 @Override
使用建议:
- 声明方法,参数尽可能使用父类
- 方法返回值,使用父类
Object类
- 所有类的父类,有几个方法一般会被重写
- toString():输出或记录日志是会使用到该方法的返回结果
- equals():在业务逻辑上判断是否是一个对象时,重写
- hashCode():
Super
- 普通方法(static方法除外):调用父类的属性和方法
- 构造方法:子类构造方法中,显式调用 父类构造方法super()
类初始化加载顺序
- 静态代码块-->代码块-->构造函数
- 父类静态代码块—>子类静态代码块—>父代码块—>父构造—>子代码块—>子构造
final
- 修饰变量,表示一个常量,一旦初始化就不可修改
- 方法中的局部变量,声明时可以赋值,或者使用前赋值
- 成员属性,可以声明时赋初始值,或者代码块中赋值
- 修饰方法,表示该方法不能被子类重写
- 修饰类,该类不能被继承
- 变量命名一般所有字母大写,且使用下划线分隔
== 和 equals
-
==
- 基本数据类型,比较大小
- 引用类型,比较内存地址
- 布尔类型不能与其他数值型比较
-
equals
- 只能使用引用类型调用,默认情况与==一样
-
实际开发会重写该方法,String,Integer等等重写了
-
类重写
// 在User类中 public boolean equals(Object obj) { // 自我比较 if(this==obj) { return true; } // 判断是否为该类 // obj为null时if不成立 if(obj instanceof user) { User u=(User)obj; return u.getName().equals(name);// 当前实例的name } return false; }
-
-
String
- 会存在常量空间
- 重写了equals
eclipse
- window ——>showView——>task 查看TODO
- alt+shift+s 重写 右键source
2019.8.9
抽象类
- abstract 修饰的类,抽象方法: 修饰符 + 方法名();
- 不能实例化,子类继承的抽象类,必须实现抽象父类所有抽象方法,或者子类也为抽象
- 可以有构造方法,被子类构造中super()调用
- 抽象方法,必须在抽象类中,抽象类不一定有抽象方法
开闭原则:对于扩展是开放的,对于修改是关闭。
接口
-
作用:一种能力的体现;一种协议
-
关键字 Interface, 实现接口 implements
-
所有的成员变量都为,public static final,声明时直接赋值
-
方法都为public abstract抽象方法,在Java 8之后提供default方法,可以具体实现,与访问修饰符不同
// 接口中 default method(){}// 可以实现
接口和抽象类不同
- 语法关键字不同,抽象类单继承,接口多实现,(除了static、抽象方法、default)
- 设计:
- 抽象类:适合表示继承层次上的实体
- 接口:表达某种能力;一种约定,解耦
相同
- 都不能实例化
- 可以有抽象方法
内部类
-
类内部 的类:实例化 outClass.InnerClass inner = new outClass.InnerClass();
-
匿名内部类:p为person的匿名内部类对象
abstract class Person { public abstract void eat(); } public class Demo { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } }
eclipse:
- 右键src restore from history选择恢复
面向对象特征
-
封装
- 将实现细节隐藏,提供外部可访问接口;更安全,访问控制符,私有属性
-
继承
- 让我们编程更加靠近人类的思维,代码复用,提高可维护,灵活
-
多态
- 动态绑定:多态是指通过指向父类的指针,来调用在不同子类中实现的方法
抽象:我们在定义一个类的时候,实际上就是把一类事物的公有的属性和行为提取出来,形成一个物理模型,这种研究问题的方法称为抽象。
网友评论