Java 封装、继承、多态

封装

将类的部分信息隐藏在类内,通过提供的固定方法访问。

访问修饰符
访问修饰符 本类 同包 字类 其他
private
默认
protected
public
this

this.属性名 用来区分局部变量和成员变量

private String name;
private int age;
Student(String name , int age){
	this.name = name ;
	this.age = age;
}
//但是如果写成name=name,就并没有把name赋给Student

this.方法名 用来访问本类的成员方法
this() 访问本类的构造方法,必须放在第一条语句(如果放在最后,会覆盖前面的)

内部类
①成员内部类

原文链接:https://blog.csdn.net/weixin_42762133/article/details/82890555

//每个内部类都可以独立的继承一个接口的实现,无论外部类是否已经继承了某个接口的实现,对内部类没有影响。
public class Outer entends ClassA implements FunctionA{

	public class Inner extends ClassB implements FunctionB{		
	}
}
//当内部类属性名和外部类属性名相同时,注意怎样从内部访问外部类属性
//当外部类要访问内部类,则新建方法,在方法里面new内部类对象,通过对象访问

/**
 * 外部类、成员内部类的定义
 */
public class Outer {

    private int outerVariable = 1;
    private int commonVariable = 2;
    private static int outerStaticVariable = 3;
    //省略getter/setter
     
    /**
     * 成员方法
     */
    public void outerMethod() {
        System.out.println("我是外部类的outerMethod方法");
    }

    /**
     * 静态方法
     */
    public static void outerStaticMethod() {
        System.out.println("我是外部类的outerStaticMethod静态方法");
    }

    /**
     * 内部类
     */
    public class Inner {
    
        private int commonVariable = 20;

        /**
         * 构造方法
         */
        public Inner() {
        }

        /**
         * 成员方法,访问外部类信息(属性、方法)
         */
        public void innerShow() {
            //当和外部类冲突时,直接引用属性名,是内部类的成员属性
            System.out.println("内部的commonVariable:" + commonVariable);
            //内部类访问外部属性
            System.out.println("outerVariable:" + outerVariable);
            //当和外部类属性名重叠时,可通过外部类名.this.属性名
            System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
            System.out.println("outerStaticVariable:" + outerStaticVariable);
            //访问外部类的方法
            outerMethod();
            outerStaticMethod();
        }
    }
    
    /**
     *	外部类访问内部类信息
     */
    public void outerShow() {
        Inner inner = new Inner();
        inner.innerShow();
    }
}

//在其他类中,创建外部类对象,通过外部类创造内部类对象

/*
*	其他类使用成员内部类
 */
public class Other {
    
    public static void main(String[] args) {
        //外部类对象
        Outer outer = new Outer();
        //创造内部类对象
        Outer.Inner inner = outer.new Inner();
        inner.innerShow();
        /*
        * 可在Outer中定义get方法,获得Inner对象,那么使用时,只需outer.getInnerInstance()即可。
        * public Inner getInnerInstance(Inner类的构造方法参数){
        *   return new Inner(参数);
        * }
        */
    }
}
②静态内部类
//静态内部类的方法只能访问外部类的static关联的信息。
//访问内部类的静态信息,直接外部类.内部类.静态信息就可以了。
//静态内部类可以独立存在,不依赖于其他外围类。
public class Outer {
	static {
        System.out.println("Outer的静态块被执行了……");
    }
    public static class Inner {
		public void innerShow() {
            System.out.println("innerVariable:" + innerVariable);
            System.out.println("内部的commonVariable:" + commonVariable);
            System.out.println("outerStaticVariable:"+outerStaticVariable);
            outerStaticMethod();
        }
        public static void innerStaticShow() {
        	//被调用时会先加载Outer类
            outerStaticMethod();
            System.out.println("outerStaticVariable"+outerStaticVariable);
        }
	}
}
③局部内部类
//类前不能有访问修饰符。
//仅在方法内使用。
//可以直接访问方法内的局部变量和参数但是不能更改。
//可以随意的访问外部类的任何信息。
public class Outer{
	private int outa = 1;
	public void outerMethod(){
		System.out.println("我是外部类的outerMethod方法")
	}
	public void outerCreatMethod(int value) {
		class Inner{
			private int innerVariable = 10;
            private int commonVariable = 20;
			/**
			*	局部内部类方法
			*/
            public void innerShow() {
                System.out.println("innerVariable:" + innerVariable);
                //调用外部类的信息
                System.out.println("outerVariable:" + outerVariable);
                System.out.println("内部的commonVariable:" + commonVariable);
                System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
                System.out.println("outerStaticVariable:" + outerStaticVariable);
                outerMethod();
                outerStaticMethod();
            }		
		}
	}
	//入口
	public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerCreatMethod(100);
    }
}
④匿名内部类
/**
 *   定义接口
 * 接口中方法默认为public 
*/
public interface IAnimal{
	void speak();
}
/**
 * 外部内、内部类
*/
public class Outer {
    public static IAnimal getInnerInstance(String speak){
        return new IAnimal(){
            @Override
            public void speak(){
                System.out.println(speak);
            }};
        	//注意上一行的分号必须有
    }
    public static void main(String[] args){
    	//调用的speak()是重写后的speak方法。
        Outer.getInnerInstance("小狗汪汪汪!").speak();
    }
}

继承

特性:
  • 子类拥有父类非private的属性、方法
  • 子类可以对父类扩展
  • 子类可用自己的方式实现父类的方法
  • Java可以多重继承,但是是单继承
  • 提高了类之间的耦合性
关键字
  • extends
  • implements
//可以间接实现多继承的特性
public interface A{}
public interface B{}
public class C implements A,B{}
  • super与this
this.function();//调用自己的方法
super.function();//调用父类的方法
  • final
//可以把类定义为不能继承的,即最终类;或者用于修饰方法,但是该方法不能被子类重写
final class 类名{}
构造器

原文链接:https://blog.csdn.net/li_jeremy/article/details/79294699

  • 创建构造器的规则
    ①构造函数名和类名相同
    ②构造函数没有显式返回值
  • 构造函数类型
//无参数
//显示默认值的默认构造函数
class Student3 {
    int id;
    String name;
    void display() {
        System.out.println(id + " " + name);
    }
    public static void main(String args[]) {
        Student3 s1 = new Student3();
        Student3 s2 = new Student3();
        s1.display();
        s2.display();
    }
}
//输出结果有值为0 null ,编译器自动提供默认构造函数,它为id和name分别提供了0和null。
//有参数
class Student4 {
    int id;
    String name;
    Student4(int i, String n) {
        id = i;
        name = n;
    }
    void display() {
        System.out.println(id + " " + name);
    }
    public static void main(String args[]) {
        Student4 s1 = new Student4(111, "Karan");
        Student4 s2 = new Student4(222, "Aryan");
        s1.display();
        s2.display();
    }
}
  • 构造函数重载
Student5(int i, String n) {
        id = i;
        name = n;
    }
Student5(int i, String n, int a) {  //通过参数的不同告知编译器此处用到了构造函数的重载
        id = i;
        name = n;
        age = a;
    }
  • 拷贝构造函数
//通过构造函数
Student6(int i, String n) {
        id = i;
        name = n;
    }
Student6(Student6 s) {  //参数传入的是类对象
        id = s.id;
        name = s.name;
    }
public static void main(String args[]) {
        Student6 s1 = new Student6(111, "Karan");
        Student6 s2 = new Student6(s1);    //将上面的s1传入
    } 
//将对象值分配给另一个对象
Student7(int i, String n) {
        id = i;
        name = n;
    }
Student7() {}
public static void main(String args[]) {
        Student7 s1 = new Student7(111, "Karan");
        Student7 s2 = new Student7();
        s2.id = s1.id;  //直接赋值
        s2.name = s1.name;
    }
Object类

Object类是所有类的父类,其中的方法适合所有子类

  • toString()
  • equals()

多态

原文链接:https://www.runoob.com/java/java-polymorphism.html

优点
  • 消除类型之间的耦合关系
  • 可替换性
  • 可扩充性
  • 接口性
  • 灵活性
  • 简化性
三个必要条件
  • 继承
  • 重写
  • 父类引用指向子类对象
//使程序有良好的扩展,并可以对所有类的对象进行通用处理
public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}
  • 重写
//当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法
//若要调用父类中被重写的方法,必须使用关键字super
多态的实现方式
重写

原文链接:https://www.runoob.com/java/java-override-overload.html

//必须是重写父类已有的方法
class Animal{
   public void move(){
      System.out.println("动物可以移动");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
   public void bark(){
      System.out.println("狗可以吠叫");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 对象
      Animal b = new Dog(); // Dog 对象
 
      a.move();// 执行 Animal 类的方法
      b.move();//执行 Dog 类的方法
      b.bark();		/////////////////////////bark在父类里面并没有,报错
   }
}

重写规则:

  • 参数列表必须完全与被重写方法的相同
  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类
  • 访问权限不能比父类中被重写的方法的访问权限更低
  • 声明为 final 的方法不能被重写
  • 声明为 static 的方法不能被重写,但是能够被再次声明
  • 构造方法不能被重写
  • 如果不能继承一个方法,则不能重写这个方法
重载

被重载的方法必须改变参数列表(参数个数或类型不一样)

public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }   
public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }   

在这里插入图片描述

接口

除非实现接口的是抽象方法,否则要实现接口中的所有方法

抽象类和抽象方法

抽象类:一个类中没有包含足够的信息来描绘一个具体的对象
抽象方法:方法的具体实现又子类确定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章