java|Java零基础(九)之面向对象三大特性

  1. 封装性(重点)
    面向对象的三大特性:封装,继承,多态
//面向对象案例:车子的发动 //分析:类: 车类对象: new属性:颜色,品牌等方法:启动 //问题: 价格可以赋值为负数--程序逻辑没问题,但数据不合理 //解决方案:在程序中对属性的值进行判断是否大于0,如果小于0,则给定一个默认值即可 //封装性:不要使用属性直接赋值与取值,而是通过方法进行封装;该方法就是set/get方法 //好处:提高安全性及复用性 //封装性操作步骤: //1.编写set/get方法 //2.属性私有化

class Car{ private String brand; //写上set和getprivate:私有权限,限制属性只能在当前类中使用 privateintprice; /*public void start() { System.out.println(brand+"品牌的汽车正在发动; 价格为:"+price); }*/ //set规范写法:set+属性名首字母大写,参数名与属性名一致 public void setPrice(int price) { //注意:此处是为了说明封装特性,才进行的逻辑判断;后续没有特殊说明,则直接赋值 if(price<0) { this.price = 100000; //给定异常数据的默认值 }else { this.price = price; } } //get规范写法: get+属性名首字母大写 public int getPrice() { return price; //可以+this吗? 可以,只是get方法中没有冲突则可省略 } public void setBrand(String brand) { this.brand = brand; } public String getBrand() { return brand; } }

public class Test { public static void main(String[] args) { Car car = new Car(); car.setBrand("红旗"); car.setPrice(-1000); System.out.println("---------"); //car.price = -10000; //加权限限制--从源头上规避异常数据的录入 car.setPrice(-10000); System.out.println(car.getPrice()+"==>"+car.getBrand()); //取值 } }

  1. 继承(重点)
    生活中的继承:施舍方的赠与,接受方的获取
    程序中的继承:两个类之间满足“is a”的关系,这样的两个类,我们可以设置为继承
    特点:有了继承关系,子类拥有父类的属性和方法
父类的选择:
在生活中满足is a关系的类很多,我们需要从中选择最合适的父类
例如: 狗类是动物类,也是生物类,也是物质类
直接父类选择动物类—特征和行为最接近
结论: 重合点越多,越接近直接父类
重合点越少,越接近Object类(祖宗类)
继承的应用:
案例: 子类有狗类,鸟类,找出他们的特征和行为
狗类:
特征: [品种,姓名,年龄],毛色
行为: [吃,睡],跑
鱼类: [品种,姓名,年龄]
特征: [吃,睡],游
【java|Java零基础(九)之面向对象三大特性】父类:动物类–共性抽取,将所有子类共有的特征和行为放入父类,子类只需继承即可
特征: 品种,姓名,年龄
行为: 吃,睡
作用:简化代码量,提高复用性
继承的共性抽取
public class Animal { String brand; String name; intage; public void eat() { System.out.println(name+"正在吃"); } public void sleep() { System.out.println(name+"正在睡"); } }//Dog类继承Animal类 class Dog extends Animal{ String color; public void run() { System.out.println(name+"正在跑.."); } }//Fish类继承Animal类 class Fish extends Animal{ public void swim() { System.out.println(name+"正在游..."); } }

public class Test { public static void main(String[] args) { Dog dog = new Dog(); //实例化子类对象 dog.name = "旺财"; //调用父类的特征 dog.color = "黄色"; //调本类的特征dog.eat(); //调父类的行为 dog.run(); //调本类的行为//匿名对象:没有名字的对象,只操作一次时,可直接new对象(匿名对象)调方法 //new Animal().run(); //注意:父类不能调子类的特征和行为 } }

多级继承案例
//细节: //不能多继承(多个父亲),但是可以多级继承(有父类,爷爷类,太爷爷类...) //多级继承的特征和行为都可以叠加//案例: //爷爷拥有100万,父亲拥有一辆宝马车,儿子拥有一个奥特曼class GrandFather{ public void haveMoney() { System.out.println("拥有100万"); } }class Father extends GrandFather{ //Son间接继承GrandFather public void haveCar() { System.out.println("拥有宝马车"); } }class Son extends Father{ //Son直接继承Father public void havePeron() { System.out.println("拥有奥特曼"); } }

public class Test { public static void main(String[] args) { Son son = new Son(); son.havePeron(); //调子类自身方法 son.haveCar(); //调父类方法 son.haveMoney(); //调间接父类方法 } }

不可继承性
  1. 父类私有的特征和行为不能被继承
  2. 构造方法不能被继承
  3. 在不同场景下的有些权限限制的特征和行为不能被继承(测试说明)
不可继承性案例1
不能被继承情况:
  1. 父类私有的特征和行为不能被继承
  2. 构造方法不能被继承-----最好测试带参构造
public class Person { private String name; //私有属性public Person() {}public Person(String name) { } }class Student extends Person{ public void study() { //System.out.println(name); //私有权限,在子类中不能继承 } }

public class Test { public static void main(String[] args) { //父类有带参构造,子类没有,通过子类调父类带参构造,会报错;说明构造方法没有继承性 //Student st = new Student("666"); } }

权限测试
在java的面向对象案例中,主要权限有:private,default,prodected,public
java|Java零基础(九)之面向对象三大特性
文章图片

不能被继承情况:
  1. 父类私有的特征和行为不能被继承
  2. 构造方法不能被继承-----最好测试带参构造
  3. 在不同场景下的有些权限不能被继承(测试说明)
public class Person { private String name; //私有属性 intage; //default权限 protected String sex; //保护权限 public String love; //公开权限public Person() {}public Person(String name) { }public void eat() { System.out.println(name); //私有权限,在本类中可以使用 System.out.println(age); //默认权限,在本类中可以使用 } }class Student extends Person{ public void study() { //System.out.println(name); //私有权限,在子类中不能继承 } }class MyTest{ public static void main(String[] args) { Person p = new Person(); //System.out.println(p.name); //私有权限,在同包不同类中不能使用 System.out.println(p.age); //默认权限,在同包不同类中能使用 System.out.println(p.sex); //保护权限,在同包不同类中能使用 System.out.println(p.love); //公开权限,在同包不同类中能使用 } }

----------下面是另一个包的类------------
public class Teacher extends Person { public void work() { //System.out.println(name); //私有权限,在不同包的子类中不能使用 //System.out.println(age); //默认权限,在不同包的子类中不能使用 System.out.println(sex); //保护权限,在不同包的子类中能使用 System.out.println(love); //公开权限,在不同包的子类中能使用 } }class Car{ public void start() { //System.out.println(love); //this.love } public static void main(String[] args) { Person person = new Person(); //System.out.println(person.name); //私有权限,在不同包,无继承关系中不能使用 //System.out.println(person.age); //默认权限,在不同包,无继承关系中不能使用 //System.out.println(person.sex); //保护权限,在不同包,无继承关系中不能使用System.out.println(person.love); //公开权限,在不同包,无继承关系中能使用 } }

  1. 继承-重写(重点,难点)
//案例:父亲和儿子吃饭的方式不同 //概述: 子类的方法和父类完全一致(返回值类型,方法名,参数类型) //子类的权限不小于父类(一般都为public)//应用场景:当父类的方法不满足子类时,子类可重写父类方法class Father{ public void eat() { System.out.println("非常绅士的吃..."); } }class Son extends Father{ @Override//重写注解,标记下面的方法是重写方法,如果不是则报错 public void eat() { System.out.println("狼吞虎咽的吃..."); } }public class Test { public static void main(String[] args) { Son son = new Son(); son.eat(); } }

  1. super使用
    回顾:this的用法–当前对象
    this.属性
    this.方法
    this调构造方法:this() this(参数)
super: 父类对象
super.属性: 调父类对象的属性
super.方法: 调父类对象的方法
super()或super(参数): 调父类的构造方法
注意:在继承关系中,this如果自身没有属性和方法,根据继承性会调用父类的
super调方法
class Father{ public void haveMoney() { System.out.println("拥有100万"); } }class Son extends Father{ /* public void haveMoney() { System.out.println("拥有100块"); }*/ public void have() { System.out.println("拥有奥特曼"); //super.haveMoney(); //调用父类的方法 this.haveMoney(); //调自身的方法,如果自身没有,则会调父类的 } }public class SuperMethod { public static void main(String[] args) { new Son().have(); } }

super调属性
class Fu{ String name="凤姐"; }class Zi extends Fu{ String name = "刘亦菲"; public void test(){ System.out.println(super.name); //调用父类的属性 System.out.println(this.name); //自己有属性,调自己的,没有才调父类的 System.out.println(name); //相当于this.name } }public class SuperField { public static void main(String[] args) { Zi zi = new Zi(); zi.test(); } }

super调构造方法
//子类实例化过程: //案例:C继承B,B继承A,实例化C的对象,查看实例化过程 //分析:当调用子类构造方法时,在构造方法中,默认会有super()放在首句; 表示先调父类无参构造; //所以最终先打印父类的无参构造,再打印子类构造//继承中,子类实例化,为何会默认调super()? 因为需要将父类资源先加载;子类才能拥有父类资源 class A /*extends Object*/{ //没有继承的父类,则直接继承Object public A() { //super(); //---调Object的无参构造 System.out.println("A的无参构造"); } }class B extends A{ public B() { //super(); System.out.println("B的无参构造"); } } class C extends B{ public C() { //super(); System.out.println("C的无参构造"); } } public class SuperTest1 { public static void main(String[] args) { C c = new C(); } }

java|Java零基础(九)之面向对象三大特性
文章图片

super与this构造方法
class AA{ public AA(){ System.out.println("AA 无参构造"); } public AA(String name) { System.out.println("AA 带参构造"); } } class BB extends AA{ public BB() { System.out.println("BB 无参构造"); } public BB(String name) { //super(); //super(name); this(); //会不会默认生成super()? 不会因为super()和this()都要出现在首句--冲突 //结论: this()和super()不能共存 System.out.println("BB 带参构造"); } } public class SuperTest2 { public static void main(String[] args) { //new BB(); //AA无参BB无参 new BB("666"); //AA无参BB带参[AA带BB带参]AA无参BB无参BB带参 } }

    推荐阅读