Java中最核心的内容就是OOP(面向对象编程)。
OOP:封装、继承、多态。
1、封装:类的成员在什么地方可以被访问。封装一般用访问修饰符来实现,公有方法封装私有属性。一般类的成员属性用private封装,通过public修饰符实现访问。
(1)类的成员:静态成员和实例成员;静态成员用static修饰,内存放在系统的全局区。可以使用类名调用也可以使用对象名调用。静态成员之间也可以相互调用,但是静态成员不能调用实例成员。而且静态类成员常驻内存实例成员:不用static修饰的类成员。必须用类的对象调用,实例成员之间可以相互调用。实例成员之间也可以调用静态成员。实例成员是new类的时候分配内存,如果没有new类之前用静态成员调用实例成员系统会发生错误。原因就是静态成员调用的实例成员系统还没有分配内存。静态成员可以调用new类之后的实例成员。
(2)构造方法:和类名相同没有返回值也没有void。构造方法的作用是初始化类的属性。子类继承父类时,父类的构造方法不能被继承。当new类时,构造方法会自动调用,如果程序中没有构造方法,系统会有一个默认的构造方法。this或super作为构造方法使用,必须在第一句
class A extends B{
public A(String n){
Super();
}
//错误
public A(){
this("aa");
super();
}
(3)方法重载:方法相同方法的签名不同。包括:方法的参数、类型、个数,与方法的返回值无关。方法重载可以实现多态。
(4)析构方法:系统回收内存。Protectedvoid finalize(){},若想要及时回收用System.gc()实现。
2、继承:简化类的设计实现多态。用extends实现类的继承。
(1)继承特点:单继承。当程序中使用接口时可以实现多继承。子类和父类规定谁的属性谁负责初始化。子类不能继承父类的构造函数。当子类调用父类的构造函数时super()写在子类构造函数的第一行。子类调用父类的构造函数时,从子类一次向父类调用,执行时从父类一次向子类执行。Protected访问修饰符就是为了实现继承儿设计。
(2)方法重写:当父类中的方法满足不了子类中的需要时可以重写父类中的方法。(父类引用指向子类对象)。这是实现程序多态的核心。
(3)Super:子类中可以用super调用父类的方法和属性。
(4)abstract:用abstract修饰类时,类就是抽象类。在父类中定义抽象类时,此父类就成为抽象类,父类中的抽象类不能被实现。子类继承父类时,父类中的抽象类必须在子类中实现,否则子类也为抽象类抽象类不允许实例化,抽象类通过定义的抽象方法用来约束子类的行为。只要类中有抽象方法,该方法必须是抽象方法。抽象方法转为继承为设计。
(5)Final修饰符:修饰方法,则方法不能被重写;修饰属性,则属性不能被修改;修饰类,则类不能被继承。
(6)接口interface:是抽象类和常量的集合。接口相当于纯抽象类。可以实现类的多继承。接口也可以像类一样的被其他子接口继承。可以通过关键字implements来实现接口。接口可以实现毫不相关的类的公有方法。只要行为相同就可以用相同的一个接口。接口也可以作为方法的参数和方法的返回值,这样更能实现多态的功能。接口是解决类的行为的问题。
3、多态:多种形态,多种行为即多态
(1)静态多态:有几个方法重载就有几种行为;
(2)动态多态:又称运行时多态,核心是父类引用指向子类对象。
方法重写:必须和父类有继承关系的方法。可以使抽象类中的抽象方法,也可以在子类中实现接口。当在子类中有和父类有继承关系的方法时,才能用父类的引用指向子类的对象。
Instanceof:判断一个对象是否是某个类的对象;返回值为true 和 false。
父类:
public abstract class Animal {
//成员方法
privateString name;//封装属性
privateString type;//用private封装
//抽象类
abstractpublic void sound();
//构造函数的方法重载
publicAnimal(String type){
this.type = type;
this.name = "unknown";
}
publicAnimal(String type,String name){
this.name = name;
this.type = type;
}
//用公有方法访问私有属性
publicString getType(){
return this.type;
}
publicString getName(){
return this.name;
}
//成员方法
publicvoid sayHello(){
System.out.println("我是"+this.type+"类,我的名字叫"+this.name);
}
}
接口:
public interface IFly {
abstractvoid fly();
}
子类一:
public class Bird extends Animalimplements IFly{
publicBird() {
super("鸟");/ /调用父类的构造函数
}
publicBird(String name) {
super("鸟",name);/ /调用父类的构造函数
}
@Override//实现父类中的抽象方法
publicvoid sound() {
System.out.println("嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎");
}
@Override//实现接口中的抽象方法
publicvoid fly() {
System.out.println("我要飞的更高");
}
}
子类二:
public class Dog extends Animal {
privateString bread;
publicDog(String bread,String name) {
super("狗",name);//用super调用父类的构造函数初始化父类中的属性
this.bread = bread;//Dog类中的属性自己初始化
}
publicDog(String bread) {
super("狗");
this.bread = bread;
}
public StringgetBread(){
return this.bread;
}
publicvoid sayHello(){
System.out.println("我是"+super.getType()+"类,我的名字叫"+super.getName()+",我的品种是"+this.bread);
}
@Override
publicvoid sound() {
System.out.println("25252525252525252");
}
}
主类:
public class PetShop {
publicstatic void main(String[] args) {
Dog d1 = new Dog("藏獒","大黄");
Dog d2 = new Dog("卷毛");
Bird b1 = new Bird("鹦鹉");
Bird b2 = new Bird();
Animal [] pets = newAnimal[]{d1,d2,b1,b2};/ / 父类引用指向子类对象(多态)
Animal pet = null;
for (int i = 0; i < 6; i++) {
intindex = new Random().nextInt(pets.length);
pet= pets[index];
pet.sayHello();/ / 必须和父类有继承关系的方法,才能用父类的对象pet来调用
pet.sound();/ / 必须和父类有继承关系的方法,才能用父类的对象pet来调用
if(pet instanceof Bird) {/ / 判断pet指的对象是否是Bird类中的对象
((Bird) pet).fly();
}
System.out.println("********************************");
}
}
}
运行时多态是通过父类和子类的类型转换来实现的。用子类表示父类时,要强制性转换。当父类表示子类时,自动转换。所以,运行时动态就是用父类指向子类的实例实现多态的。