继承、封装、多态

访问权限的修饰符

访问权限的修饰符一共有四种:private,默认,protected,public

private默认protectedpublic
类(非内部类)NYNY
方法YYYY
属性YYYY

权限修饰符在类上:

如果类有public 是可以随便访问的(包括跨文档);
如果 默认 的话,同包内能访问,跨包不能访问。

权限修饰符在属性或者方法上:

作用域同一个类同包子孙类无关类
publicYYYY
protectedYYYN
默认YYNN
privateYNNN

通常情况下:类一般设置成public的,属性一般都是private,方法一般都是public的,也有少数使用protected,private。

继承

描述类的时候,如果发现几个类有重复的属性和方法,就可以采用继承的方式来继承。

继承语法:使用extends关键字来继承
class 子类 extends 父类{
   子类属性
   子类方法
}

1、使用 extends 指定父类;
2、Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承)3、子类会继承父类的所有 public 的字段和方法;
4、对于父类的 private 的字段和方法,子类中是无法访问的;
5、子类的实例中,也包含着父类的实例,可以使用 super 关键字得到父类实例的引用;

继承的特点:

1、子类使用extends 关键字继承父类的共同属性以外,子类还可以有自己特有的属性或者方法;
2、父类更通用,子类更具体;
3、子类只能获得父类中的非private的属性,如果想要继承就得提供公共的 set和get方法,私有的方法是无法继承下来的;
4、java中只能做单继承(一个子类只能继承一个父类 );

在类的继承结构中,如果创建一个子类的对象,那么会在子类的对象的内部常见一个父类的对象,
如果通过子类的对象访问属性的时候,子类中没有该属性,就会到父类的对象中查找,
调用方法的时候也是一样的,如果子类中没有该方法,就会到父类中查找。

protected 关键字

对于类的调用者来说,protected 修饰的字段和方法是不能访问的;
对于类的子类和同一个包的其他类来说,protected 修饰的字段和方法是可以访问的。

final 关键字

功能:限制类被继承

1、如果 final 修饰在变量上,这个变量不能修改。

2、如果 final 修饰在属性上,要么直接初始化,要么在构造器中初始化,
如果存在多个构造器,每一个构造器里面都必须要有 final 修饰的这个属性的初始化。

3、如果 final 修饰在方法上,final修饰的方法不能被覆写。

4、如果 final 修饰在类上,这个类就不能被继承。

语法:
权限修饰符 final 返回值类型 方法名(参数列表){
   方法体
} 

super 关键字

如果需要在子类内部调用父类方法怎么办? 使用 super 关键字。

super 表示获取到父类实例的引用

a) 使用 super 来调用父类的构造器

public Bird(String name) { 
	 super(name); 
}

b) 使用 super 来调用父类的普通方法

public class Bird extends Animal { 
 	public Bird(String name) { 
 		super(name); 
 	} 
 	
 	@Override 
 	public void eat(String food) { 
 		// 修改代码, 让子调用父类的接口. 
 		super.eat(food); 
 		System.out.println("我是一只小鸟"); 
 		System.out.println(this.name + "正在吃" + food); 
 	} 
}
1.子类通过默认构造器实例化的过程中,父类的构造器先被调用,
然后再调用子类的构造器,在子类构造器内部默认调用 super();

class JavaTeacher extends Teacher{
	boolean isGlass;
    public JavaTeacher(){
		super();   //隐藏调用父类的构造器
                   //写不写,都存在
      	System.out.println(...);
   	}
}

注意:

1、如果父类带有 有参数的构造器,并且没有显示的定义父类的默认构造器,默认构造器被覆盖,
导致子类的构造器无法通过 super() 来做调用,就会编译报错,需要显示的定义父类的默认的构造器。

2、子类通过构造器实例化时要调用父类的默认构造器,是隐含的调用了 super()这个方法。
但是如果子类的构造器中调用了父类中的有参数的构造器,那么无参数的构造器就不会被调用了。

3super() 的调用必须要放在方法的第一行。

4super() 可以表示父类的引用,我们可以使用superthis 来区分父类和子类中同名的属性。
在子类中访问属性的查找顺序首先在子类中查找指定的属性名字,
如果在子类中没有该属性,那么就去父类中去查找该属性。
方法也是一样的,当子类和父类有同样的方法时,通过子类调用的这个相同的方法时调用的是子类的方法。
但是我们可以通过super对父类的引用来调用父类的方法。

super().方法();    //super 调用父类方法

this关键字:

1、代表当前类的指定实例的引用
2、可以区分同名的属性和局部变量
3、通过this可以调用同类中的构造器(this(),this(参数列表)4、调用本类里面的属性,this.属性名,this.方法()

如果父类、子类有重名的属性,this就是子类的属性
No区别thissuper
1概念访问本类中的属性和方法由子类访问父类中的属性、方法
2查找范围先查找本类,如果本类没有就调用父类不查找本类而直接调用父类
3特殊表示当前对象

封装

提高数据安全性,通过封装,可以实现对属性的访问权限控制,同时增加了程序的可维护性。

private 实现封装:

将属性私有化,使用 private关键字 完成属性私有化,这种属性只有本类能访问。
(在其他类中,通过调用 这个类的公有方法,从而间接访问 这个类的私有属性)
如果需要获取或者修改这个 private 属性,就需要使用 getter / setter 方法。

class Girl{
	private String name;
 	private int age;
    private String tel;    //封装

    public void setName(String myName){   //给 name 赋值
    	name=myName;
    }
    public String getName(){    //获取 name
        return name;
    }
    public void setAge(String myAge){
        age=myAge;
    }
    public int getAge(){
        return age;
    }

    //对象方法
    public void playGame(){
        System.out.println(this.name+"玩游戏");
        System.out.println(name);    //隐藏的就是 this
    }
    public void sleep(){
        System.out.println(this.name+"睡觉");
        playGame();     //this.playGame();    省略 this,this就是调用playGame的p
      				    //对象方法调用对象方法
    }
}
public class TeatGirl{
	public static void main(String[] args){
		Girl g=new Girl();
        g.setName("一一");    //通过公有的方法设置属性
        g.setAge(18);
        String myName=g.getName();    //通过公有的方法获取属性的值
        int myAge=g.getAge();
        g.playName();     //this 相当于 p   (this.name/p.name)    即:哪个引用调 this,this 就相当于 哪个
    } 
}

多态

多态就是行为具有表现多种功能的能力。
继承多态,不仅仅是父类时抽象类,父类是普通类也是可以的。

多态的条件:
1、子类对父类有方法重写
2、父类的引用指向子类的实例(子类转换成父类),
  调用 覆写的这个方法 的时候,调用的是子类的方法。

向上转型:

Bird bird = new Bird("圆圆"); 
Animal bird2 = bird; 

// 或者写成下面的方式
Animal bird2 = new Bird("圆圆"); 

// bird2 是一个父类(Animal)的引用,指向一个子类(Bird)的实例,这种写法称为“向上转型”。

动态绑定:
当子类和父类中出现同名方法的时候, 再去调用会出现什么情况呢?

// Animal.java
public class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("我是一只小动物");
        System.out.println(this.name + "正在吃" + food);
    }
}

// Bird.java 
public class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    public void eat(String food) {
        System.out.println("我是一只小鸟");
        System.out.println(this.name + "正在吃" + food);
    }
}

// Test.java 
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal("圆圆");
        animal1.eat("谷子");
        Animal animal2 = new Bird("扁扁");
        animal2.eat("谷子");
    }
}

// 运行结果
我是一只小动物
圆圆正在吃谷子
我是一只小鸟
扁扁正在吃谷子
1、animal1 和 animal2 虽然都是 Animal 类型的引用,
但 animal1 指向 Animal 类型的实例,animal2 指向 Bird 类型的实例。

2、animal1 和 animal2 分别调用 eat 方法,
而 animal1.eat() 实际调用了父类的方法,animal2.eat() 实际调用了子类的方法。

在 Java 中,调用某个类的方法,究竟执行了哪段代码(是父类方法的代码还是子类方法的代码),
要看究竟这个引用指向的是父类对象还是子类对象,这个过程是程序运行时决定的(而不是编译期)

使用多态的优点:
封装是让类的调用者不需要知道类的实现细节;
多态能让类的调用者连这个类的类型是什么都不必知道,只需要知道这个对象具有某个方法即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值