面向对象4

一、抽象类

1.1、抽象类概述

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
抽象类特点
抽象类和抽象方法必须用abstract关键字修饰
格式

abstract class 类名 {}
public abstract void eat();

抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法

1.2、抽象类的成员特点

成员变量
可以是变量
也可以是常量
构造方法
有构造方法,但是不能实例化,用于子类访问父类数据的初始化
成员方法
可以有抽象方法 限定子类必须完成某些动作
也可以有非抽象方法 提高代码服用性

public class Test {
    public static void main(String[] args) {
        Animal a=new Cat();
        a.eat();
    }
}
abstract class Animal{
    abstract  public void eat();
}
class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
}
 abstract class Dog extends Animal{
    abstract  public void eat();
 }

1.3、练习

public class Test {
    public static void main(String[] args) {
        Dog d1 = new Dog();
        d1.setName("旺财");
        d1.setAge(10);
        System.out.println(d1.getName()+"---"+d1.getAge());
        System.out.println("=======");
        Dog d2 = new Dog(10, "旺财");
        System.out.println(d2.getName()+"---"+d2.getAge());
        System.out.println("=======");
        Animal a1= new Dog();
        a1.setName("旺财");
        a1.setAge(10);
        System.out.println(a1.getName()+"---"+a1.getAge());
        System.out.println("======");
        Animal a2 = new Dog(10, "旺财");
        System.out.println(a2.getName()+"---"+a2.getAge());
    }
}
abstract class Animal{
  private  int age;
  private String name;

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Animal() {
    }

    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;
    }

    abstract public void eat();
}

class Cat extends Animal{
    public Cat(int age, String name) {
        super(age, name);
    }

    public Cat() {
    }

    public void eat(){
        System.out.println("猫吃鱼");
    }
}

class Dog extends Animal{
    public Dog(int age, String name) {
        super(age, name);
    }

    public Dog() {
    }

    public void eat(){
        System.out.println("狗吃骨头");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Teacher t= new Basic();
        t.age=20;
        t.name="张三";
        t.teach();
        System.out.println(t.name+"---"+t.age);
        System.out.println("====");
        t=new Work();
        t.name="李四";
        t.age=30;
        t.teach();
        System.out.println(t.name+"---"+t.age);

    }
}
abstract class Teacher{
    String name;
    int age;
    public abstract  void teach();
}
class Basic extends Teacher{
    public void teach(){
        System.out.println("javaSE");
    }
}
class Work extends Teacher{
    public void teach(){
        System.out.println("javaEE");
    }
}

1.4、abstract不能和哪些关键字共存

private 冲突,私有后就不能继承,也就不能重写了
final 冲突 ,同样是不能继承,也就不能重写了
static 无意义,静态方法可以用类名调用,而抽象方法没有方法体,就算能调用也毫无意义。

二、接口

2.1、接口概述

Java中提供了接口来定义额外功能,并不给出具体实现,
接口特点
接口用关键字interface表示
格式:interface 接口名 {}
类实现接口用implements表示
格式:class 类名 implements 接口名 {}
接口不能实例化,但是可以按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
接口的子类
要么是抽象类
要么重写接口中的所有抽象方法

2.2、接口成员特点

成员变量
只能是常量
默认修饰符 public static final
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
成员方法
只能是抽象方法
默认修饰符 public abstract

public class Test {
    public static void main(String[] args) {
        AA a=new AAple();
        System.out.println(a.num1);
        System.out.println(a.num2);
    }
}
interface AA{
    public static final int num1=20;
    public static final int num2=200;                  //成员变量默认为静态常量
    public abstract void show();                       //成员方法默认为抽象方法
}
class AAple implements AA{
   public void show(){
       System.out.println("show");
   }
}

2.3、类与类,类与接口以及接口与接口的关系

类与类
继承关系,只能单继承,但是可以多层继承
类与接口
实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口

public class Test2 {
    public static void main(String[] args) {
        Fu f=new Zi();
        f.show();
        Mu m=new Zi();
        m.show2();
    }
}
interface Fu{
    public abstract void show();
}
interface Mu{
    public abstract void show2();
}
class Zi implements Fu,Mu{
    public void show(){
        System.out.println("show");
    }
    public void show2(){
        System.out.println("show2");
    }
}

接口与接口
继承关系,可以单继承,也可以多继承

public interface Zi extends  Fu,Mu {
}
interface  Fu{
    public abstract void show1();
}
interface Mu{
    public abstract void show2();
}

2.4、抽象类和接口的区别

成员区别:
抽象类 变量,常量;有抽象方法;非抽象方法
接口 常量;抽象方法
关系区别:
类与类 继承,单继承
类与接口 实现,单实现,多实现
接口与接口 继承,单继承,多继承
设计理念区别:
抽象类 被继承体现的是:”is a”的关系。共性功能
接口 被实现体现的是:”like a”的关系。扩展功能

2.5、练习

public class Test {
    public static void main(String[] args) {
        JumpCat jc=new JumpCat();
        jc.name="波斯猫";
        jc.age=2;
        System.out.println(jc.name+"==="+jc.age);
        jc.eat();
        jc.sleep();
        jc.jump();
    }
}
interface  Jump{
    public abstract void jump();
}
abstract class Animal{
    String name;
    int age;
    public abstract void eat();
    public  void sleep(){
        System.out.println("睡觉");
    }
}
class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
}
class Dog extends Animal{
    public void eat(){
        System.out.println("狗吃骨头");
    }
}
class JumpCat extends Cat implements Jump{
    public void jump(){
        System.out.println("跳高猫");
    }
}
class JumpDog extends Dog implements Jump{
    public void jump(){
        System.out.println("跳高狗");
    }
}

三、形式参数和返回值问题

3.1、形式参数

基本类型

public class Test {
    public static void main(String[] args) {
        int num=21;
        show(num);
    }
    public static void show(int a){
        System.out.println(a);
    }
}

引用类型
类:

public class Test2 {
    public static void main(String[] args) {
        Student s = new Student();
        s.show(s);
    }
}
class Student{
    public void show(Student s){
        System.out.println("show");
    }
}

抽象类:

public class Test3 {
    public static void main(String[] args) {
        new FuDemo().method(new Zi());
    }
}
abstract class Fu{
    public abstract  void  show();
}
class Zi extends Fu{
    public void show(){
        System.out.println("show");
    }
}
class FuDemo{
    public void method(Fu f){
       f.show();
    }
}

接口:

public class Test4 {
    public static void main(String[] args) {
        new FatherDemo().method(new Son());
    }
}
interface Father{
    public abstract void show();
}
class Son implements Father{
    public void show(){
        System.out.println("show");
    }
}
class FatherDemo{
    public void method(Father f){
        f.show();
    }
}

3.2、返回值类型

基本类型

public class Test2 {
    public static void main(String[] args) {
        int num1=1;
        int num2=2;
        int sum = show(num1, num2);
        System.out.println(sum);
    }
    public static int show(int a,int b){
        return a+b;
    }
}

引用类型
类:

public class Test1 {
    public static void main(String[] args) {
        new StudentDemo().method().show();

    }
}
class Student{
    public void show(){
        System.out.println("show");
    }
}
class StudentDemo{
    public Student method(){
        return new Student();
    }
}

抽象类:

public class Test2 {
    public static void main(String[] args) {
        new FuDemo().method().show();
    }
}
abstract class Fu{
    public abstract void show();
}
class Zi extends Fu{
    public void show(){
        System.out.println("show");
    }
}
class FuDemo{
    public Fu method(){
        return new Zi();
    }
}

接口:

public class Test3 {
    public static void main(String[] args) {
        new FatherDemo().method().show();
    }
}
interface Father{
    public abstract void show();
}
class Son implements Father{
    public void show(){
        System.out.println("show");
    }
}
class FatherDemo{
    public Father method(){
        return new Son();
    }
}

四、内部类

4.1、内部类概述

把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有。
外部类要访问内部类的成员,必须创建对象。

4.2、内部类位置

按照内部类在类中定义的位置不同,可以分为如下两种格式:

成员位置(成员内部类)
class Outer{
    class Inner{
        
    }
}
局部位置(局部内部类)
class Outer{
    public void show(){
        class Inner{
            
        }
    }
}

4.3、成员内部类

外界如何创建对象
外部类名.内部类名 对象名 = 外部类对象.内部类对象;

public class Test {
    public static void main(String[] args) {
        Outer.Inner oi=new Outer().new Inner();
        oi.show();
    }
}
class Outer{
    private int num=10;
    class Inner{
        public void show(){
            System.out.println(num);
        }
    }
}

4.4、成员内部类的常见修饰符

成员内部的常见修饰符:
1、private 为了保证数据的安全性
2、static 为了让数据访问更方便
被静态修饰的成员内部类只能访问外部类的静态成员
成员内部类被静态修饰后的访问方式是:
格式:

外部类名.内部类名 对象名 = new 外部类名.内部类名();

4.5、成员内部类的面试题

要求:使用已知的变量,在控制台输出302010class Outer {
			public int num = 10;
			class Inner {
				public int num = 20;
				public void show() {
					int num = 30;
					System.out.println(num);//30
					System.out.println( Inner.this.num);//20
					System.out.println( Outer.this.num); //10
				}
			}
		}
		class InnerClassTest {
			public static void main(String[] args) {
				Outer.Inner oi = new Outer().new Inner();
				oi.show();
			}	
		}

4.6、局部内部类访问局部变量的问题

1、可以直接访问外部类的成员
2、可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
3、局部内部类访问局部变量的注意事项:
必须被final修饰
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。

class Outer{
  private  int num=100;
  public void show(){
    final  int num2=200;
      class Inner{
          public void show2(){
              System.out.println(num);
              System.out.println(num2);
          }
      }
      Inner inner = new Inner();
      inner.show2();
  }
}

4.7、匿名内部类

就是内部类的简化写法。
前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类。
格式:
new 类名或者接口名() {重写方法;}
本质:
是一个继承了类或者实现了接口的子类匿名对象

public interface Inner {
    public abstract void show();
}
class Outer{
    public void method(){
        new Inner(){
            @Override
            public void show() {
                System.out.println("show");
            }
        }.show();
    }
}
class Test{
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
}
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
}
interface Inner{
    public abstract void show1();
    public abstract void show2();
}
class Outer{
    public void method(){
       Inner in= new Inner(){
            @Override
            public void show1() {
                System.out.println("show1");
            }

            @Override
            public void show2() {
                System.out.println("show2");
            }
        };
       in.show1();
       in.show2();
    }
}

4.8、匿名内部类面试题

按照要求,补齐代码
		interface Inter { 
			void show(); 
		}
		
		class Outer { 
			//补齐代码 
			
		}
		
		class OuterDemo {
			public static void main(String[] args) {
				  Outer.method().show();
			  }
		}
		要求在控制台输出”HelloWorld”
interface Inter {
			void show(); 
		}
		
		class Outer { 
			public static Inter method(){
			Inter in= new Inter(){
					@Override
					public void show() {
						System.out.println("helloworld");
					}
				};
			return in;
			}
		}
		
		class OuterDemo {
			public static void main(String[] args) {
				  Outer.method().show();
			  }
		}

版权声明:本文为xuefeiyuan1995原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。