欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 封装、继承、多态

程序员文章站 2024-03-16 23:31:46
...

封装

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

访问修饰符
访问修饰符 本类 同包 字类 其他
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";
    }   

Java 封装、继承、多态

接口

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

抽象类和抽象方法

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