类成员的加载顺序
没有继承关系的加载顺序
关于关键字static,大家都知道它是静态的,相当于一个全局变量,也就是这个属性或者方法是可以通过类来访问,当class文件被加载进内存,开始初始化的时候,被static修饰的变量或者方法即被分配了内存,而其他变量是在对象被创建后,才被分配了内存的。
所以在类中,加载顺序为:
1.首先加载静态字段或者静态语句块
3.普通变量以及语句块
4.构造方法被加载
注意静态加载时的顺序由其定义的先后有关
package Inherit;
public class Demo {
// 属性
int b = 20;
static int a = 10;
{
System.out.println("构造代码块");
System.out.println(b);
}
// 方法
public void getA() {
System.out.println(b);
System.out.println("普通方法");
}
static {
System.out.println("静态代码块");
System.out.println(a);
}
public static void getB() {
System.out.println(a);
System.out.println("静态方法");
}
public static void main(String[] args) {
Demo demo = new Demo();
}
}
首先会执行的是static修饰:
静态属性和静态代码块,权重是一样的,因此根据顺序加载
之后加载是属性和构造代码块,它们也是一样的,顺序决定谁先加载
访问修饰符
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
只有默认和public可以写在类前面 protected、private不能修饰类
一般属性:用private修饰 ,方法:用public修饰
面向对象的三大特性
-
封装
-
继承
-
多态
有的会含有抽象
封装
什么是封装
- 首先是抽象,把事物抽象成一个类,其次才是封装,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系
为什么需要封装:
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员进行更精确的控制。
4、隐藏信息,实现细节。
封装的目的:数据的安全性和私密性
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其getter setter方法的类,没有业务逻辑,有时可以作为VO(value -object)或dto(Data Transform Object)来使用.当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也不能携带有connection之类的方法。
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
子类的创建可以增加新数据、新功能,可以继承父类全部的功能,但是不能选择性的继承父类的部分功能。继承是类与类之间的关系,不是对象与对象之间的关系。
【1】类是对对象的抽象:
【2】继承是对类的抽象:
先写父类,再写子类:
父类:人类 Person
子类:学生类 Student
package Inherit;
public class Person {
// 属性:
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
// 方法:
protected void eat() {
System.out.println("可以吃饭......");
}
public void sleep() {
System.out.println("睡觉.......");
}
}
package Inherit;
public class Student extends Person {// 子类Student 继承 父类Person
// 属性:
private int sno;// 学号
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
// 方法:
public void study() {
System.out.println("可以学习");
}
public void eat() {
System.out.println("我不吃");
}
}
继承的好处:提高代码的复用性,父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了
需要注意的点:
父类private修饰的内容,子类实际上也继承,只是因为封装的特性阻碍了直接调用,但是提供了间接调用的方式,可以间接调用。
继承具有传递性:
Student --》继承自 Person —》继承自Object
Object类是所有类的根基父类。
所有的类都直接或者间接的继承自Object。
多态
什么是多态?
多态就是多种状态:同一个行为,不同的子类表现出来不同的形态。多态指的就是同一个方法调用,然后由于对象不同会产生不同的行为。
多态跟属性无关,多态指的是方法的多态,而不是属性的多态。
public class Animal {//父类:动物:
public void shout(){
System.out.println("我是小动物,我可以叫。。。");
}
}
public class Cat extends Animal{
//喊叫方法:
public void shout(){
System.out.println("我是小猫,可以喵喵叫");
}
}
public class Dog extends Animal{
//喊叫:
public void shout(){
System.out.println("我是小狗,我可以汪汪叫");
}
}
public class Girl {
//跟猫玩耍:
/*public void play(Cat cat){
cat.shout();
}*/
//跟狗玩耍:
/*public void play(Dog dog){
dog.shout();
}*/
//跟小动物玩耍:
public void play(Animal an){
an.shout();
}
}
public class Test {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
//具体的猫:--》猫的对象
//Cat c = new Cat();
//具体的小女孩:--》女孩的对象
Girl g = new Girl();
//小女孩跟猫玩:
//g.play(c);
//具体的狗---》狗的对象:
//Dog d = new Dog();
//小女孩跟狗玩:
//g.play(d);
//具体的动物:--》动物的对象:
//Cat c = new Cat();
//Dog d = new Dog();
Pig p = new Pig();
Animal an = p;
g.play(an);
}
}
多态的好处:
为了提高代码的扩展性,符合面向对象的设计原则:开闭原则。
开闭原则:指的就是扩展是 开放的,修改是关闭的。
多态的要素:
一,继承: Cat extends Animal ,Pig extends Animal, Dog extends Animal
二,重写:子类对父类的方法shout()重写
三, 父类引用指向子类对象:
重写
发生在子类和父类中,当子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
子类的方法名字和父类必须一致,参数列表(个数,类型,顺序)也要和父类一致。
重写后子类的权限要大于父类
重载和重写的区别:
重载:在同一个类中,当方法名相同,形参列表不同的时候 多个方法构成了重载
重写:在不同的类中,子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
覆盖和重写是相同的概念
super关键字
super:指的是: 父类的
super可以修饰属性,可以修饰方法;
在子类的方法中,可以通过 super.属性 super.方法 的方式,显示的去调用父类提供的属性,方法。在通常情况下,super.可以省略不写
在特殊情况下,当子类和父类的属性或方法重名时,你要想使用父类的属性或方法,必须加上修饰符super.,只能通过super.属性来调用
super修饰构造器
平时写的构造器的第一行都有:super() -->作用:调用父类的空构造器,只是我们一般都省略不写
Object类
所有类都直接或间接的继承自Object类,Object类是所有Java类的根基类。
也就意味着所有的Java对象都拥有Object类的属性和方法。
如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
instanceof 关键字
用来判断对象是否是某个类的实例
if(obj instanceof class)
如果是返回true 否则方法false
final关键字
1.final 修饰变量,该变量就会称为常量,不能够在被修改(runtime)。
//final修饰一个变量,变量的值不可以改变,这个变量也变成了一个字符常量
final int A = 10;//final修饰基本数据类型
//A = 20; 报错:不可以修改值
2.final 可以修饰类,一旦final修饰类,该类就是最终类,不允许被继承
一旦一个类被final修饰,那么里面的方法也没有必要用final修饰了(final可以省略不写)
public final class Person{
public void say(){
}
}
class Student extends Person{//报错
@Override
public void say(){
}
}
3.final 还可以修饰方法,该方法为最终方法,该方法不允许重写(Override)
为什么String类会设计为final修饰
1.性能的考虑:
比如,当字符串常量池中有一个"aaa"字符串的时候,另外一个String对象的值也为"aaa",实际上就并没有创建一个新的字符串而是将引用指向了这个"aaa";这就节省了内存的开销,提高了效率,网上还有说用编译器对final修饰的类性能上有提升的,这个我没去研究,大家可以去找找看;
2.出于安全性考虑:
处理同一个String类的对象的时候值是不能改变的,比如说如果值改变的话,那其他引用该对象的值也相应的发生改变,这样就造成了安全性的问题。
nt extends Person{//报错
@Override
public void say(){
}
}
3.final 还可以修饰方法,该方法为最终方法,该方法不允许重写(Override)
------
为什么String类会设计为final修饰
> 1.性能的考虑:
> 比如,当字符串常量池中有一个"aaa"字符串的时候,另外一个String对象的值也为"aaa",实际上就并没有创建一个新的字符串而是将引用指向了这个"aaa";这就节省了内存的开销,提高了效率,网上还有说用编译器对final修饰的类性能上有提升的,这个我没去研究,大家可以去找找看;
> 2.出于安全性考虑:
> 处理同一个String类的对象的时候值是不能改变的,比如说如果值改变的话,那其他引用该对象的值也相应的发生改变,这样就造成了安全性的问题。