java类与对象
-
对象实例化的几种方式
(1)new关键字
MyObject myObject=new MyObject();
(2)反射
//首先获取类对象
Class<?> classObject=Class.forName(“test.MyObject”);//第一种根据类的路径及名称
//Class<?> classObject=MyObject.class;//第二种直接显示获取
//Class<?> classObject=new MyObject().getClass();//第三种通过new的方式获取
//获取类对象的构造器
Constructor<?> constructor=classObject.getConstructor();
//通过构造器实例化出该类的对象
MyObject myObject=(MyObject) constructor.newInstance();
//获取类的所有public属性,包括继承于父类的public属性
//Field [] fields=classObject.getFields();
//获取类的所有属性,但不能获取继承于父类的属性,获取的private属性不可被操作和获取的
Field [] fields=classObject.getDeclaredFields();
for(Field field:fields) {
//设置访问权限是可访问的及更改private属性的临时访问权限
field.setAccessible(true);
System.out.println(field.getName()+":"+field.get(myObject));
}
//获取该类属性名为"name"的属性,如果名字对应的属性不存在或名字为null将抛出异常
Field field=classObject.getDeclaredField(“name”);
//判定该属性值的访问权限,true是可访问,false不可访问
if(!field.isAccessible()) {
field.setAccessible(true);
}
//将实例化对象myObject的field属性的值设为"hah"
field.set(myObject,“hah”);
System.out.println(myObject.getName());
System.out.println(field.get(myObject));
//获取类的所有public方法,包括继承于父类的方法
//Method []methods=classObject.getMethods();
//获取类的所有方法,但不能获取继承于父类的方法,获取的private方法不可被操作和获取的
Method []methods=classObject.getDeclaredMethods();
for(Method method:methods) {
//设置访问权限是可访问的及更改private方法的临时访问权限
method.setAccessible(true);
System.out.println(method.getName());
}
//获取该类方法名为"setName"的方法,参数类型是String类型的
Method method=classObject.getDeclaredMethod(“setName”,String.class);
//对myObject调用获取的method方法
method.invoke(myObject, “我改名字了”);
System.out.println(classObject.getDeclaredMethod(“getName”).invoke(myObject));
(3)通过clone方法进行实例化
首先实现Cloneable接口,重写clone方法:
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
然后通过已有对象获取新的实例化对象:
MyObject myObject=new MyObject();
try {
MyObject myObject2=(MyObject) myObject.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(4)通过序列化方法实例化
MyObject myObject=new MyObject();
myObject.setName(“我在反序列化”);
try {
//建立文本输出流
FileOutputStream outputStream=new FileOutputStream(“C:\Users\fft13\Desktop\test.txt”);
//将文本输出流适配为对象输出流
ObjectOutputStream out = new ObjectOutputStream(outputStream);
//将myObject的信息写入对象输出流的指向文本中
out.writeObject(myObject);
out.close();
outputStream.close();
//建立文本输入流
FileInputStream inputStream=new FileInputStream(“C:\Users\fft13\Desktop\test.txt”);
//将文本输入流适配为对象输入流
ObjectInputStream in=new ObjectInputStream(inputStream);
//根据对象输入流获取的信息创建一个新的实例化对象
MyObject myObject2=(MyObject) in.readObject();
in.close();
inputStream.close();
System.out.println(myObject2.getName());
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} -
类的初始化顺序
优先加载关联类
同时加载静态变量和静态代码块(根据java代码的顺序加载,如果期间有非静态成员参与静态成员的初始化,非静态成员将被提前初始化)
然后加载非静态变量和非静态代码块(根据java代码的顺序加载)
最后初始化构造方法 -
抽象类与接口
(1)抽象类与接口的区别
抽象类可以有自己的构造方法,接口不能有自己的构造方法;
抽象类可以有自己的实现方法,接口不能有实现方法;
抽象类可以有各种类型的方法,接口只能是public的方法;
子类只能继承一个抽象类(extens),但能实现多个接口(implements);
子类只必须实现抽象类的抽象方法,但接口的所有方法必须实现。
(2)抽象类与接口的用法及意义
抽象类的意义在于为子类定义一个公共类型,封装子类共用属性和方法,抽象子类需要不同实现的方法;
接口的意义在于定义规范、约束、回调; -
父类与子类
子类只能重写父类的实例方法,子类不能继承于父类的private属性和方法。 -
面向对象的特征
封装,继承,多态。
封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承:可以让某个类型的对象获得另一个类型的对象的属性的方法。
多态:一个类实例的相同方法在不同情形有不同表现形式。
多态的体现:重载(相同的方法名不同的参数),重写(重写父类的方法),实现接口。
多态的好处:可替换性,可扩展性,接口性,灵活性,简化性。 -
面向对象的设计原则
单一职责原则:在一个类中只做与自己直接相关的事情。
开放封闭原则:对修改封闭,对扩展开发。
里氏替换原则:任何基类可以出现的地方,子类一定可以出现。
依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。
接口分离原则:尽量定义职责单一的接口,而不是把所有的方法都定义在一个接口。
迪米特法则(最少知道原则):一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。还有就是对类的操作过程和属性进行影藏,对外只提供最终结果的操作接口。
合成/复用原则:尽量减少继承的使用,而使用对象组合的方式。