面向过程和面向对象编程思维
面向过程(POP):所有步骤依次执行,注重执行的细节
面向过程(OOP):创建解决问题的对象,让各个对象调用各自的方法而配合完成。
在面向对象编程OOP中,给类中定义的方法,具体的实现过程,其实也是面向过程的。
对象、类
Object(对象):
指某个类的具体实例
Class(类):
是拥有相同属性和行为的对象的集合。是类的模板。
定义类:
修饰符 class 类名{
//属性:定义变量
//行为:定义方法
}
创建对象:
类名 变量名 = new 构造方法([参数]);
成员变量、局部变量、静态常量:
成员变量:定义在类中的变量,即类的属性。它有默认值。通过对象访问。
局部变量:定义在方法中的变量。它没有默认值。只能在方法中赋值后才能使用。
静态常量:特殊的成员变量,用final static修饰。它有默认值。通过类名访问。
class Person{
//成员变量
String name;
//静态常量
final static String COUNTRY="中国";
//定义方法
void info(){
//局部变量
int age=20;
System.out.println("我叫"+name+",今年"+age+"岁,是一个"+COUNTRY+"人");
}
}
构造方法:
构造方法是一种特殊的方法。方法名和类名一致,没有返回值部分。
访问修饰符 类名(){
}
1.没有返回值部分,方法名必须和类名一致。
2.在使用new关键字创建对象时,调用对应的构造方法。
3.每个类在定义后,都隐藏有一个无参的构造方法。 如果自定义了有参数的构造方法,无参数的构造方法就会失效。如果想要使用无参构造方法,就要再写出来。
4.构造方法通常用于限制创建对象时携带的参数,初始化成员变量。
5.构造方法之间都是重载关系,构造方法不能重写。
6.构造方法执行时,不一定会创建对象。如抽象类中有构造方法,但无法创建抽象类对象,只能在创 建抽象类的子类对象时,自动调用抽象类的构造方法。
面向对象三大特性
封装:
将类中的属性使用private修饰,这样就能防止非当前类对其访问。
封装的步骤:
1.给类中的所有属性添加private访问修饰符
2.给每个属性添加getXXX()方法用于读取属性值
3.给每个属性添加setXXX()方法用于给属性赋值
继承:
类A extend 类B。类A就是类B的子类,类A的对象就能直接访问类B中非私有成员。或接口A extends接口B。
重写Override:
子类继承父类后,对父类中的非私有方法进行重写,达到拓展或重做的目的。
1.必须满足方法名、返回值、参数列表都相同。
2.访问权限不能比父类中的方法更严格。
3.不能抛出比父类中的方法更大的异常。
重载:
在一个类中,某个方法在不同的参数下,表现不同的行为。
1.同名不同参。 方法名必须相同
2.参数列表必须不同(类型和数量)
3.无返回值无关
this和super:
都可以当做对象或构造方法使用。
1.当做对象时:this表示当前类的对象,super表示当前类的父类对象。
2.this或super当做对象使用时,只能用在非静态方法中。
3.当做构造方法:this()表示当前类的无参数构造方法,如果带参数就表示对应参数的构造方法。
4.super()表示当前类的父类的无参数构造方法,如果带参数就表示对应参数的构造方法。
5.this()或super()只能用在另一个构造方法的首行。
在继承关系中,如果父类和子类都没有写出来任何构造方法时,子类有一个隐藏的无参数构造方法,会 自动调用父类中无参数的构造方法。
class Father{
}
class Son extends Father{
/*
这个构造方法是隐藏的
*/
public Son(){
super();
}
}
如果父类中有带参数的构造方法,没有无参数的构造方法时,子类必须要调用父类中的构造方法。
class Father{
String name;
public Father(String name){
this.name=name;
}
}
class Son extends Father{
public Son(){
super("xxx");
}
}
Object类:
1.是所有类的父类。任何类都间接地继承了该类,但没有明确地使用extends体现出来。所有类都可以访 问Object类中的方法,或对其进行重写。
2.toString()就是Object类中的一个方法,在输出对象时自动调用。默认输出的是"类名@十六进制哈希 码",通常在自定义类中,重写toString(),从而输出该类中的属性。
3.equals()也是Object类中的一个方法,用于比较两个对象是否相同。默认使用==比较,即比较内存地 址,通常需要重写该方法,自定义判断两个对象是否相同时所需的参数。
向上转型(子类对象可以直接使用父类变量保存,即多态。):
Person p = new Person();
Object obj = p;
向下转型:
Animal an = new Aniaml();
//Animal必须是Cat的父类
Cat c =(Cat) an;
多态:
在继承关系中,子类的对象可以保存到父类的变量中。
多态通常应用于定义方法时,形参为一个父类或接口类型变量,实参可以是子类对象。
无法通过父类变量调用子类独有的方法,如果调用重写了父类的方法时,执行重写后的内容。
父类/父接口 对象 = new 子类();
public class Father{
public void smoke(){
System.out.println("father smoking");
}
}
public class Son extends Father{
public void play(){
System.out.println("son playing");
}
@Override
public void smoke(){
System.out.println("son smoking");
}
}
public class Main(){
public static void main(String[] args){
Father f = new Father();
f.smoke();//父类中的方法
Son son = new Son();
son.play();
son.smoke();//调用的是重写后的方法
//多态
Father father = new Son();
//father.play();无法调用
father.smoke();//调用的是重写后的方法
}
}
访问修饰符
当前类 | 当前包 | 不同包中的子类 | 不同包中的非子类(同一个项目中的不同类) | |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
不写 | √ | √ | × | × |
private | √ | × | × | × |
final
用于修饰属性、方法和类
修饰属性:变量变为常量,不能改变其中的值。
修饰方法:方法成为最终方法,不能重写。
修饰类:类成为最终类,不能被继承。
abstract
用于修饰类和方法,表示抽象的。
修饰方法,方法成为抽象方法,没有方法体,同时该方法的所在类也一定要用abstract修饰,让其成为 抽象类。
1抽象方法只能出现在抽象类中,不能出现在普通类中。
2.抽象类中可以没有抽象方法。
3.抽象类中有构造方法,但该构造方法只会在new抽象类的子类对象时会自动调用,抽象类不能创建 自身对象。
4.抽象类通常需要被继承,一旦有子类继承了抽象类,就必须要重写抽象类中的所有抽象方法。
interface
用于定义接口的关键字。代替class。
如果某个抽象类中全都是抽象方法时,可以将这个类改为接口。
1.接口是一个完全抽象类,其中的方法都是public abstract修饰的抽象方法,没有方法体,其中的属性都是public final static修饰的静态常量。
2.接口中没有构造方法,不能创建对象。
3.接口通过implements实现,实现它的类称为该接口的实现类。
4.一个类可以同时实现多个接口。
5.一个类实现了接口后,必须重写其中的抽象方法。
6.JDK1.8后,可以在接口中定义default方法和static方法,该方法不用重写。
static
可以修饰方法、属性或代码块。被修饰的内容称为静态成员。
静态成员在类加载时就会保存到内存中,所以访问静态成员时,无需对象,直接通过类名即可访问。
当某个属性或方法被高度重用时,可以将其定义为静态的,之后通过类名调用。
还可以在类中定义静态代码块static{},在类加载时自动执行的代码块。
1.静态方法中无法使用非静态成员
2.普通方法中可以使用静态成员