高级OOP
1 继承
是一种基于已有类创建新类的机制
class 子类名 extends 父类{
类体;
}
public class Extends_v1 {
public static void main(String[] args) {
Extendsclass01 ex = new Extendsclass01();
}
}
class Baseclass01{
public int num;
public void setNum(int n){
num = n;
}
}
class Extendsclass01 extends Baseclass01{
}
- 通过继承,子类继承了父类的除了构造方法的全部属性和方法
- Java中只存在单继承
1.1 继承时权限的变化
- 父类的public成员在子类中也是public
- 父类的private成员在子类中变成不可访问权限
- 子类新增成员方法不可访问不可访问成员,但是父类原有的方法可以访问
public class Extends_v2 {
public static void main(String[] args) {
Extendsclass02 ex = new Extendsclass02();
ex.setNum(2);
System.out.println(ex.getNum());
}
}
class Baseclass02{
private int num;
public void setNum(int n){
num = n;
}
public int getNum(){
return num;
}
}
class Extendsclass02 extends Baseclass02{
}
1.2 子类对象的构造
构造顺序:
-
先构造父类对象
-
再构造子类新增部分
-
子类构造方法再调用之前,先调用父类构造方法
子类对象里包含一个父类对象,父类对象通过父类构造函数进行初始化,其它属性通过子类对象初始化
public class Extends_v3 {
public static void main(String[] args) {
Extendsclass03 ex = new Extendsclass03();
}
}
class Baseclass03{
Baseclass03(){
System.out.println("父类构造函数");
}
}
class Extendsclass03 extends Baseclass03{
Extendsclass03(){
System.out.println("子类构造函数");
}
}
1.3 成员变量的隐藏和方法的重写
**成员变量的隐藏:**子类和父类的属性名重复,则继承自父类的属性被隐藏
**方法的重写:**子类中声明的方法,方法名、参数列表与父类中某个方法完全一致,返回值类型与父类该方法返回值类型一致或是其子类型,则父类方法被重写
public class Extends_v4 {
public static void main(String[] args) {
Extendsclass04 ex = new Extendsclass04();
System.out.println(ex.num1);
System.out.println(ex.num2);
System.out.println(ex.getNum1());
System.out.println(ex.getNum2());
ex.output();
}
}
class Baseclass04{
public int num1 = 1;
public int num2 = 2;
public int getNum1(){
return num1;
}
public void output(){
System.out.println("这是父类");
}
}
class Extendsclass04 extends Baseclass04{
public int num1 = 3;
public int num2 = 4;
public int getNum2(){
return num2;
}
public void output(){
System.out.println("这是子类");
}
}
//输出结果
3
4
1
4
1.4 super关键字
作用:
- 调用父类构造方法,为父类构造方法传参
- 访问父类被隐藏的属性
- 调用父类被重写的方法
public class TestSuper {
public static void main(String[] args) {
Extendsclass06 ex = new Extendsclass06(1, 2);
System.out.println(ex.num1 + " " + ex.num2);
}
}
class Baseclass06{
public int num1;
public int num2;
Baseclass06(int n1, int n2){
num1 = n1;
num2 = n2;
}
}
class Extendsclass06 extends Baseclass06{
public Extendsclass06(int n1, int n2){
super(n1, n2);
}
}
public class TestSuper_v2 {
public static void main(String[] args) {
Extendsclassv2 ex = new Extendsclassv2();
ex.output();
}
}
class Baseclassv2{
public int num1 = 1;
public int num2 = 2;
}
class Extendsclassv2 extends Baseclassv2{
public int num1 = 3;
public int num2 = 4;
public void output(){
System.out.println(num1);
System.out.println(num2);
System.out.println(super.num1);
System.out.println(super.num2);
}
}
public class TestSuper_v3 {
public static void main(String[] args) {
Extendsclassv3 ex = new Extendsclassv3();
ex.fun();
}
}
class Baseclassv3{
public void output(){
System.out.println("这是父类");
}
}
class Extendsclassv3 extends Baseclassv3{
public void output(){
System.out.println("这是子类");
}
public void fun(){
output();
super.output();
}
}
1.5 final关键字
作用:
- 类不能被继承
- 方法不能重写
- 属性值不能改变
- 对于方法中的局部变量
- 基本类型的值不能改变
- 引用类型的指向对象不能改变
2 对象向上转型
是指父类的引用指向子类的对象
class Father{
}
class Son{
}
public class Test{
public static void main(String[] args){
Father f = new Son();
}
}
特点:
- 父类引用不可以访问子类新增的成员(属性与方法)
- 父类引用访问父类中被隐藏属性是子类继承的属性
- 父类引用调用被子类重写的方法时调用的是重写过的方法
public class UpCasting {
public static void main(String[] args) {
Father f = new Son();
//访问子类的特有成员
//System.out.println(f.num3);
//System.out.println(f.fun3());
//调用被子类覆盖的成员
System.out.println(f.num1);
f.fun1();
}
}
class Father{
public int num1 = 1;
public int num2 = 2;
public void fun1(){
System.out.println("这是父类fun1");
}
public void fun2(){
System.out.println("这是父类fun2");
}
}
class Son extends Father{
public int num1 = 3;
public int num3 = 4;
public void fun1(){
System.out.println("这是子类fun1");
}
public void fun3(){
System.out.println("这是子类fun3");
}
}
3 多态
是指同样的方法作用在不同的对象时产生的不同的效果。
多态产生的条件:
- 继承
- 方法重写
- 对象向上转型
- 动态绑定
public class Polymorpyhrism {
public static void say(animal a){
a.say();
}
public static void main(String[] args) {
dog d = new dog();
cat c = new cat();
bird b = new bird();
say(d);
say(c);
say(b);
}
}
class animal{
public void say(){
System.out.println("AAA");
}
}
class dog extends animal{
public void say(){
System.out.println("www");
}
}
class cat extends animal{
public void say(){
System.out.println("mmm");
}
}
class bird extends animal{
public void say(){
System.out.println("jjj");
}
}
4 抽象方法和抽象类
抽象方法:
- 只允许声明不允许实现的方法
- 需要使用abstract修饰
- 必须在抽象类中声明
抽象类:
- 使用关键词abstract声明
- 可以包含普通方法和抽象方法
- 可以被继承,但是不可以用来创建对象
- 子类必须重写全部抽象方法
public class TestAbstact {
public static void main(String[] args) {
//使用子类引用创建对象
extendsAbstact ex1 = new extendsAbstact();
//使用父类引用创建对象
Abstactclass ex2 = new extendsAbstact();
//使用抽象类创建对象 失败
//Abstactclass ex3 = new Abstactclass();
ex1.fun1();
ex2.fun2();
ex2.fun1();
ex2.fun2();
}
}
abstract class Abstactclass{
public void fun1(){
System.out.println("这是抽象类的普通方法");
}
public abstract void fun2();
}
class extendsAbstact extends Abstactclass{
//必须重写,否则无法继承
@Override
public void fun2() {
System.out.println("这是子类重写的抽象方法");
}
}
5 接口
是一种特殊的类,只包含公共抽象方法,静态常量
interface 接口名{
[public][static][final] 数据类型 属性名;
[public][abstract] 返回值类型 方法名(形参列表);
}
- 接口不能被实例化,但是可以被其他类实现
- 一个类只能继承一个父类,但是可以实现多个接口
- 如果一个类需要实现一个接口,那他就要实现接口的全部方法
public class TestInterface {
public static void animalCrazy(Animal an){
an.run();
an.say();
}
public static void main(String[] args) {
Animal dog = new dog_inter();
Animal snake = new cat_inter();
Animal bird = new bird_inter();
animalCrazy(dog);
animalCrazy(snake);
animalCrazy(bird);
}
}
interface Animal{
public abstract void say();
void run();
}
class dog_inter implements Animal{
public void say(){
System.out.println("汪汪汪......");
}
public void run(){
System.out.println("四条腿跑");
}
}
class cat_inter implements Animal{
public void say(){
System.out.println("喵喵喵......");
}
public void run(){
System.out.println("被追着跑");
}
}
class bird_inter implements Animal{
public void say(){
System.out.println("咕咕咕......");
}
public void run(){
System.out.println("翅膀飞");
}
}
public class TestInterface_v2 {
public static void main(String[] args) {
student s = new student();
s.read();
s.write();
}
}
interface read1{
void read();
}
interface write1{
void write();
}
class student implements read1, write1{
public void read(){
System.out.println("学生在阅读");
}
public void write(){
System.out.println("学生在写作业");
}
}
}
public class TestInterface_v2 {
public static void main(String[] args) {
student s = new student();
s.read();
s.write();
}
}
interface read1{
void read();
}
interface write1{
void write();
}
class student implements read1, write1{
public void read(){
System.out.println("学生在阅读");
}
public void write(){
System.out.println("学生在写作业");
}
}