目录
1.封装:
1.1 好处:
- 隐藏实现的细节
- 可以验证数据,保证安全(合理输入)
1.2 方法:
- 属性私有化,无法进行外部修改
- 提供一个public方法,用于对属性判断并赋值
- 提供一个公共的get方法,用于获取属性的值
class animal{
//1.成员属性私有化
private String name;
private int age;
private float weight;
private float height;
//2.公共的get方法
public String getName() {
return name;
}
//3.公共的set方法
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
// 构造器
public animal(){
}
//调用方法进行校验
public animal(String name,int age, float weight, float height) {
setName(name);
setAge(age);
setWeight(weight);
setHeight(height);
}
//方法:
void InformationOutput(){
System.out.println("animal Name is " + this.name);
System.out.println("animal Age is " + this.age);
System.out.println("animal Weight is " + this.weight);
System.out.println("animal height is " + this.height);
}
static void Clear(){
this.name =null;
this.age = 0;
this.height =0.0f;
this.weight = 0.0f;
}
}
快捷键 alt+insert 支持一键生成
4.封装和构造器结合:
创建构造器无参和有参,在构造器中调用方法
public animal(){
}
//调用方法进行校验
public animal(String name,int age, float weight, float height) {
setName(name);
setAge(age);
setWeight(weight);
setHeight(height);
}
2.继承
语法:class 子类 extends 父类{}
class Cat extends animal{
//2.构造器
public Cat(){
//super(); //默认调用
}
public Cat(String name, int age, float weight, float height) {
// 4.super()可以指定调用构造器,放在第一行
super(name, age, weight, height);
}
}
- 解决代码复用,子类继承了父类所有的方法和属性,但是私有属性不可以直接访问,要通过创建公共方法去访问(指在父类提供一个public方法去访问父类的私有属性)
- 子类必须调用父类的构造器,完成初始化(被迫自动调用)
子类构造器中隐藏了super():默认调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类构造器中用super(形参列表为 指定父类构造器的形参列表)去指定父类的有参构造器去完成父类的初始化工作,否则编译无法通过
super()可以指定调用构造器,放在第一行
super()和this()在构造器中不能共存
Java所有类都是Object的子类
父类构造器调用不限于直接父类,可一直向上追溯到object类
Java是单继承机制,只能继承一个父类
不能滥用继承,子类与父类必须满足is-a机制
2.2 内存机制
- new 子类的时候 ,在堆里开个地址,先在 方法区 查找加载最顶端的父类(object),再往下逐渐加载。
- 对于引用数据,堆里放父类的引用地址,指向方法区常量池的引用数据,基本数据类型则在堆里存储
- 对于继承类,在堆里再开空间,即便是重名变量,也不是同一个数据,地址是不一样的
- 将地址赋给栈里的对象
访问属性规则:查找关系返回(如果本类有该属性并且可以访问,则可以直接访问本类中的属性,如果本类没有该属性或者不可直接访问,就会判断父类,以此类推,直至满足,没有就报错,但如果只要被挡了,就会不再寻找直接报错)
注:父类私有的属性是有内存的,只是无权访问,除了在父类创建公开方法去访问(详见上面)
2.3 super关键字
1.访问父类属性,方法(private无权限)
2.访问父类构造器,只能放在第一句并且只能出现一次
2.4 super 和this区别
this | super | |
调用属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找. | 访问父类中的属性 |
调用方法 | 访问本类中的方法,如果本类没有此方法则从父类中继续查找. | 直接访问父类中的方法 |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子构造器的首行 |
特殊 | 表示当前对象 | 子类中访问父类对象 |
2.5 方法重写
1.子类父类方法参数,方法名要完全一样
2.返回类型 子类返回类型是父类返回类型或子类
3.子类访问权限符不能缩小权限
@Override
void InformationOutput() {
System.out.println("Cat Name is " + getName());
System.out.println("Cat Age is " + getAge());
System.out.println("Cat Weight is " + getWeight());
System.out.println("Cat height is " + getHeight());
}
2.6 属性重写
属性没有重写,访问对象属性的时候看对象的编译类型(等号左边),而不是运行类型(等号右边)。
3.多态
多态是一种性质
1.对于方法来说,重载是方法多态的体现
public static int sum(int ...num){
int sum = 0;
for(int i = 0;i < num.length ;i++){
sum += num[i];
}
return sum;
}
public static float sum(float ...num){
float sum = 0;
for(int i = 0;i < num.length ;i++){
sum += num[i];
}
return sum;
}
2.性质的多态
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的.
(4)编译类型看定义时=号的左边,运行类型看=号的右边
以animal和cat为例:
@SuppressWarnings("all")
class animal{
//1.成员属性私有化
private String name;
private int age;
private float weight;
private float height;
public String classname = "Animal";
//4.代码块
{
System.out.println("animal类或其子类对象被创建");
}
//2.构造器
public animal(){
}
//调用方法进行校验
public animal(String name,int age, float weight, float height) {
setName(name);
setAge(age);
setWeight(weight);
setHeight(height);
}
//3.成员方法
void InformationOutput(){
System.out.println("animal Name is " + this.name);
System.out.println("animal Age is " + this.age);
System.out.println("animal Weight is " + this.weight);
System.out.println("animal height is " + this.height);
}
void Clear(){
this.name =null;
this.age = 0;
this.height =0.0f;
this.weight = 0.0f;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
}
子类:
//1.在cat中添加独有成员color 属性和 jump方法
@SuppressWarnings("all")
class Cat extends animal{
public String classname = "Cat";
private String color;
//2.构造器
public Cat(){
}
public Cat(String name, int age, float weight, float height,String color) {
super(name, age, weight, height);
this.color = color;
}
@Override
void InformationOutput() {
System.out.println(this.classname +" Name is " + getName());
System.out.println(this.classname +" Age is " + getAge());
System.out.println(this.classname +" Weight is " + getWeight());
System.out.println(this.classname +" height is " + getHeight());
System.out.println(this.classname +" color is " + this.color);
}
void jump(){}
}
3.1 动态绑定机制:
1.不能直接访问子类独有的属性(cat.color),父类受访问修饰符限制的属性(cat.name...),访问的属性是父类的属性(属性看等号左边的编译类型)
2. 运行的方法是子类的方法,不能使用子类特有的方法(cat.jump())(方法看等号右边的运行类型)
3.2 向上转型
class main2{
public static void main(String[] args) {
//向上转型 用子类的构造器去创建父类的实例对象(向上转型时,在堆里面开了一个 Cat)
animal cat = new Cat("tom",3,5.4f,0.53f,"white");
System.out.println(cat.getClass() ); //cat类型
System.out.println(cat instanceof animal); //true
//动态绑定机制
//1.不能直接访问子类独有的属性(cat.color),父类受访问修饰符限制的属性(cat.name...),访问的属性是父类的属性
System.out.println(cat.classname); //Animal
//2. 运行的方法是子类的方法,不能使用子类特有的方法(cat.jump())
cat.InformationOutput();
/*
Cat Name is tom
Cat Age is 3
Cat Weight is 5.4
Cat height is 0.53
Cat color is white*/
}
}
3.3 向下转型(类似于强转)
1)语法:子类类型引用名=(子类类型)父类引用;
2)只能强转父类的引用,不能强转父类的对象
3)要求父类的引用必须指向的是当前目标类型的对象
4)可以调用子类类型中所有的成员
//只有子类被向上转型到的父类才能进行向下转型,且必须转移到本子类,否则会抛出类异常
Cat cat1 = (Cat)cat;
//编译不会报错,但运行时会发生异常
Dog dog = (Dog)cat;
// Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog
3.4多态数组
先完善dog类:
class Dog extends animal{
public String classname = "Dog";
public String color2;
public Dog(String color2) {
this.color2 = color2;
}
public Dog(String name, int age, float weight, float height, String color2) {
super(name, age, weight, height);
this.color2 = color2;
}
void bark(){}
}
在创建一个多态数组:
animal[] animals = new animal[3];
animals[0] = new animal("A",1,1,1);
animals[1] = new Dog("J",1,1,1,"b");
animals[2] = new Cat("T",1,1,1,"w");
for(int i = 0;i< animals.length; i++){
System.out.println(animals[i].getClass());
}
// class animal
// class Dog
// class Cat
for(int i = 0;i< animals.length; i++){
System.out.println(animals[i] instanceof animal);
}
// true
// true
// true
for(int i = 0;i< animals.length; i++){
System.out.println(animals[i] instanceof Dog);
}
// false
// true
// false
for(int i = 0;i< animals.length; i++){
System.out.println(animals[i] instanceof Cat);
}
// false
// false
// true
3.5 多态形参
形参声明为父类类型,实参类型允许为其子类类型