面向对象编程OOP
面向对象是相对于面向过程来说的。面向过程就是每个过程都需要自己去完成,而面向对象,就是,你把自己想象成一个大老板,然后你不用直接干活,你是发号施令的那一个,你让自己的手下员工去干活,各司其职,宣传的就做宣传,产品的就做生产,财务的就理财等等,该干啥活就干啥活,不能去干其他活。
类
抽象的一类事物,如人类
对象
具体的一类事物,如某人
//简单地定义一个类,包括成员变量与方法
public class A {
int id;
String name;
public void a(){
System.out.println("a");
}
}
//在启动类里面创建该类的对象,并调用方法
public class Application {
public static void main(String[] args) {
A a = new A();//通过new去创建A这个类的实例化对象
a.id = 1;
a.a();
}
}
构造器
与类名相同无返回值的方法,也不能写void。
创建对象时,会调用构造器,实例化初始值。
无参构造默认存在
public class B {
public B() {
}
}
存在含参构造的情况下,无参构造不会默认存在,需要手动定义。
public class B {
int id;
//无参构造
public B() {
}
//含参构造
public B(int id) {
this.id = id;
}
}
调用含参构造
B b1 = new B(1);
面向对象三大特性
封装
//广义的封装,将属性和方法封装成一个类
public class Games {
//private 让属性私有化,封装起来,狭义的封装。然后再通过get和set方法操作属性。
private String name;
private int HP;
private int power;
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
}
Games player1 = new Games();
player1.setHP(2100);
int hp = player1.getHP();
继承
定义一个父类/基类/超类
public class Games {
private int good;
public void play(){
System.out.println("The game can be play");
}
public int getGood() {
return good;
}
public void setGood(int good) {
this.good = good;
}
}
定义一个子类/派生类
public class DarkSoulThree extends Games{}
子类基础父类,使用关键字extends,并且默认继承Object类。
DarkSoulThree player1 = new DarkSoulThree();
player1.play();//子类可以使用父类的公共方法,但是不能使用父类私有化的资源
final修饰的类是最终类,没有子类
This和super
父类的资源
public class Games {
int fire = 10;
public void play(){
System.out.println("The game can be play");
}
}
子类的属性资源
private int fire = 8;
public void test(int fire){
System.out.println(fire);
System.out.println(this.fire);//指向本类的fire这个属性
System.out.println(super.fire);//指向父类的fire这个属性
}
子类的方法
public void play(){
System.out.println("Learning how to write die about Chinese");
}
public void test(){
play();//本类方法
this.play();//指向本类方法
super.play();//指向父类方法
}
This()和super()
super在创建对象时会调用父类构造器
父类无参
public Games() {
System.out.println("父类无参");
}
子类无参和含参
public DarkSoulThree() {
super();//默认隐藏代码,并且位置一定在第一行,不写也默认存在。此处调用父类无参构造。如果无无参构造,需要手动写出调用父类的任意一个有参构造
this(1);//调用其他含参构造时,必须上面super()不写出来,并且调用的该构造器不能调用本构造器,不然会陷入死循环。
System.out.println("子类无参");
}
public DarkSoulThree(int fire) {
this.fire = fire;
System.out.println(fire);
System.out.println(this.fire);
}
//创建子类对象
DarkSoulThree player1 = new DarkSoulThree();
运行结果为
父类无参
1
1
子类无参
重写
前提:继承,子类重写父类非静态、非常量、非私有的方法。
方法名和参数列表一样,修饰符一样或者更大范围,抛出异常一样或者缩小,返回值类型一样或者缩小(返回值类型不能是原来返回值类型的父类)
//父类原方法
public class A {
public void test(){
System.out.println("a-test");
}
}
//子类重写的方法
public class B extends A{
@Override//非静态方法可以重写,重写即是重新写出和父类同名同参数列表的方法
public void test(){
System.out.println("b-test");
}
}
//创建对象并调用
public class Application{
public static void main(String[] args) {
A a = new A();
a.test();
B b = new B();
b.test();
A a1 = new B();//向上转型
a1.test();//该方法如果为静态,则调用A类的方法,因为这是类资源,a1为该类保存的对象;反之,则调用B类的重写后的方法。
}
}
多态
多态对象的创建
//父类
public class C {
int id = 1;
public void test(){
System.out.println("c");
}
}
//子类
public class D extends C {
int id = 2;
public void test(){
System.out.println("d");
}
public void test1(){
System.out.println("1d");
}
}
//创建对象
public class Application{
public static void main(String[] args) {
D d = new D();
//创建多态对象
C c = new D();//向上转型
Object o = new D();
d.test();//调用父类的方法,如果子类重写后调用子类的重写后的方法。
c.test();//多态对象调用父类方法,子类重写后调用子类的重写后的方法。
d.test1();//调用本类方法
// c.test1();//多态没法调用子类特有方法。
((D)c).test1();//向下转型,通过强制类型转化可以调用子类方法。
System.out.println(c.id);//多态只能使用父类的成员变量。
}
}
instance of
判断有没有父子关系
//父类
public class C {}
//子类1
public class D extends C {}
//子类2
public class E extends C{}
//创建对象并判断
public static void main(String[] args) {
D d = new D();
C c = new D();//向上转型
Object o = new D();
System.out.println(o instanceof D);//是否属于D类,true
System.out.println(o instanceof C);//是否属于C类,true
System.out.println(o instanceof Object);//是否属于Object类,true
System.out.println(o instanceof E);//是否属于E类,false
System.out.println(o instanceof String);//是否属于String类,false
System.out.println(c instanceof D);//是否属于D类,true
System.out.println(c instanceof C);//是否属于C类,true
System.out.println(c instanceof Object);//是否属于Object类,true
System.out.println(c instanceof E);//是否属于E类,false
// System.out.println(c instanceof String);//是否属于String类,false
System.out.println(d instanceof D);//是否属于D类,true
System.out.println(d instanceof C);//是否属于C类,true
System.out.println(d instanceof Object);//是否属于Object类,true
// System.out.println(d instanceof E);//是否属于E类,false
// System.out.println(c instanceof String);//是否属于String类,false
}
static关键字
让成员变量或者方法成为类资源,当有这个关键字修饰时,会和类一同加载,无需创建对象即可使用。
**使用方法:**本类直接调用,别类需用该类类名去调用。
public class F {
private static int id;//静态变量
private int num;//非静态变量
public void f1(){
f2();//非静态的方法可以直接调用静态的方法
}
public static void f2(){}
public static void main(String[] args) {
F f = new F();
f.num = 1;//非静态变量只能创建对象调用
f.id = 0;
F.id = 1;//静态变量在类加载时候就有了,所以可以直接用类来调用。
id = 2;
f.f1();//非静态方法只能创建对象调用
f.f2();
F.f2();//静态方法在类加载时候就有了,所以可以直接用类来调用。
f2();//同类下直接调用,静态方法只能直接调用静态方法
}
}
代码块
public class G {
{
System.out.println("匿名代码块");
}//代码块,匿名代码块/构造代码块,创建对象时优先加载,可以初始化一些值。由于每次new一个对象时都会优先加载,所以,可以用来对于new出来对象时构造方法需要做的重复的代码放在构造代码块里面。
static {
System.out.println("静态代码块");
}//代码块,静态代码块,只执行一次,类加载时就会加载
public G() {
System.out.println("构造方法");
}
public static void main(String[] args) {
new G();
}
}