很多初学者反应,面向对象这部分知识点好难、很绕、内容很抽象不好理解等等。其实面向对象真的不难,只是有些书本上或者视频教程里把它讲得太抽象了,讲得太细了也会让我感觉内容很多、很乱,最终导致学晕了。
这里我不会用一些专业语言去描述面向对象的相关的概念、因为一旦描述了很多概念会让初学者误以为概念很重要,其实重在理解,这也不是语文考试。我将采用一种全新的方式,引导你自己去理解相关内容。
类与对象理解
少废话先看图
从图中我们可以看出,类是对具有相同属性和行为的事物的统称,而对象是这类事物的一种具体表现。
属性是指着类事物的静态特征(如电脑的品牌、价格、颜色、尺寸、出厂日期、保修期等),而行为指的是这类事物能够干什么(如电脑能够看电影、玩游戏、写代码、制作表格、绘制图形等)
下面那Java代码是如何表示类的呢?格式如下
public class 类名{
成员变量--属性
成员方法--功能
}
下面我们用Java代码类描述一个电脑类,每一个电脑都有品牌和价格,每一个电脑都能够玩游戏。这里品牌和价格就是电脑得属性,玩游戏就是电脑得行为。
//电脑类
public class Computer {
//三个属性:品牌、价格
String brand;//品牌
int price;//价格
//打游戏功能
public void playGame(){
System.out.println("使用"+brand+"品牌电脑打游戏");
}
}
上面仅仅只是定义了一个电脑类,相当于设计师设计出电脑轮廓和功能,需要工厂的工人根据设计师的要求把电脑造出来(贴上Logo,标上价格…),造出来的具体的电脑就是电脑对象。
public class Demo1{
public static void main(String[] args){
//创建一个电脑对象
Computer apple=new Computer();
apple.brand="苹果";
apple.price=5768;
apple.playGame();//用苹果电脑玩游戏
//创建另一个电脑对象
Computer huawei=new Computer();
huawei.brand="华为";
huawei.price=5288;
huawei.playGame();//用华为电脑玩游戏
}
}
一个标准类的组成
定义类的格式为public class 类名{}
,在类的{}
里只能有下面几部分组成
成员变量: 一般把成员变量使用private修饰,提供get和set方法
构造方法: 用于创建对象,同时可以给成员变量赋值
成员方法: 被对象调用
警告1:除了测试类,其他类都按照类的组成规则写
警告2:类中的属性和方法一定要和这个类相关,不要张冠李戴
public class Student{
//成员变量
private String name;//姓名属性
private int age;//年龄属性
//构造方法,仅用于创建对象
public Student(){
}
//全参数构造方法,用于创建对象同时给name和age赋值
public Student(String name,int age){
this.name=name;
this.age=age;
}
//获取对象的name属性值
public String getName(){
return name;
}
//设置对象的name属性值
public void setName(String name){
this.name=name;
}
//获取对象的age属性值
public int getAge(){
return int ;
}
//设置对象的age属性值
public void setAge(int age){
this.age=age;
}
}
##继承和抽象
少废话看图
我们发现继承是抽取子类的共性,子类继承父类可以具备了父类的属性和行为。继承的关键字extends
Animal类:描述共性的属性和行为
//抽象类Animal
public abstract class Animal{
//成员变量表示属性
private String variety;//品种
private String color;//颜色
private int age;//年龄
//空参数构造方法
public Animal(){}
//有参数构造方法
public Animal(String variety,String color,int age){
this.variety=variety;
this.color=color;
this.age=age;
}
//构造方法、get和set按照标准类的写法,自己生成(alt+insert)
//吃的行为:但是不知道吃什么abstract修饰
public abstract void eat();
//睡的行为:但是不知道怎么睡abstract修饰
public abstract void sleep();
//呼吸:我把呼吸定义成一个具体方法(ps:为了告诉你抽象类中可以有具体方法)
public void breath(){
System.out.println("所有动物都会呼吸");
}
}
定义Dog类 继承Animal类
//Dog 继承 Animal,必须复写Animal的抽象方法
public class Dog extends Animal{
//Dog虽然继承Animal,但是创建Dog对象还是得看Dog的构造方法
public Dog(){}
//有参数构造方法
public Dog(String variety,String color,int age){
super(variety,color,age); //访问父类构造,给成员变量赋值
}
@Override
public void eat(){
System.out.println("狗吃骨头");
}
}
定义Cat类 继承Animal类
//Cat 继承 Animal,必须复写Animal的抽象方法
public class Cat extends Animal{
//Cat 虽然继承Animal,但是创建Cat 对象还是得看Cat 的构造方法
public Cat (){}
//有参数构造方法
public Cat (String variety,String color,int age){
super(variety,color,age); //访问父类构造,给成员变量赋值
}
@Override
public void eat(){
System.out.println("猫吃小鱼");
}
}
测试类:程序的入口仅用于创建对象调用方法
public class Demo2{
public static void main(String[] args){
//利用空参数构造创建Dog对象
Dog dog=new Dog();
dog.setVariety("哈士奇");//给dog对象设置品种为"哈士奇"
dog.setColor("黑白");//给dog对象设置颜色为"黑白"
dog.setAge(2);//给dog对象设置年龄为2岁
//调用get方法获取dog对象的属性值
System.out.println(dog.getVaritey()+"..."+dog.getColor()+"..."+dog.getAge());
System.out.println("----------------------");
//利用有参数构造创建对象,并赋值
Cat cat=new Cat("布偶猫","白色",3);
//如果想显示dog对象的的属性值,就调用get方法并输出
//调用get方法获取cat对象的属性值
System.out.println(cat.getVaritey()+"..."+cat.getColor()+"..."+cat.getAge());
}
}
抽象类与多态
多态和继承是密不可分的,没有继承就没有多态。少废话看图
假设有一个老师既能教小学生,也能教大学生。小学生学习小学数学,大学生学习高等数学。用代码体现
分析:
1. 小学生、大学生都是学生,这就是继承关系。
2. 小学生、大学生都有姓名和年龄以及学习的行为,抽取到学生类中
3. 老师具备教学生的行为(ps: 既能教小学生,也能教大学生)
//学生类
public abstract class Student{
private String name;
private int age;
//构造方法、get和set自行脑补
//学习功能,不确定学什么抽象
public abstract void study();
}
//小学生类
public class PrimaryStudent extends Student{
//学习功能: 小学生学小学数学
public void study(){
System.out.println("小学生学习小学数学");
}
}
//小学生类
public class CollegeStudent extends Student{
//构造方法、get和set自行脑补
//学习功能: 大生学高等数学
public void study(){
System.out.println("大学生学习高等数学");
}
}
//老师类
public class Teacher{
//老师既能教大学生,也能教小学生(ps:多态体现,Student既能接收小学生,也能接收大学生)
public void teach(Student stu){
//如果stu是小学生,stu.study()就是执行【小学生的方法】
//如果stu是大学生,stu.study()就是执行【大学生的方法】
stu.study();
}
}
//测试类
public class Demo3{
public static void main(String[] args){
Teacher t=new Teacher();
//老师教小学生
t.teach(new PrimaryStudent("小明",8));
//老师教大学生
t.teach(new CollegeStudent("奶茶妹妹",20));
}
}
接口与多态
接口和抽象类的用法非常类似,几乎可以通用。但是设计思想有所不同
接口: 体现规则
抽象类:体现子类共性
少废话先看图
//接口Usb规范
public interface Usb {
//常量
public static final String color="蓝色";
public static final long MAX_TRANS_SPEED=640*1024;//640MB
//加载驱动
public void loadDriver();
//传输数据
public void trandate();
}
//U盘 遵守 Usb的规范
public class U盘 implements Usb {
@Override
public void loadDriver(){
System.out.println("加载U盘驱动");
}
@Override
public void trandate(){
System.out.println("U盘传输数据最高速率:"+Usb.MAX_TRANS_SPEED);
}
}
//Usb网卡 遵守 Usb的规范
public class Usb网卡 implements Usb {
@Override
public void loadDriver(){
System.out.println("加载Usb网卡驱动");
}
@Override
public void trandate(){
System.out.println("网卡盘传输数据最高速率:"+Usb.MAX_TRANS_SPEED);
}
}
//电脑类
public class Computer{
//电脑按照Usb的规范,使用遵守Usb规范的设备
public void other(Usb usb){
usb.loadDriver();
usb.trandate();
}
}
//测试类,仅做调用即可
public class Demo3{
public static void main(String[] args){
Computer com=new Computer();//创建电脑对象
com.other(new U盘());//电脑使用U盘的功能
com.other(new Usb网卡());//电脑使用Usb网卡的功能
}
}
修饰符总结
权限修饰符 | 作用 |
---|---|
private | 只能在本类被访问 |
public | 整个项目中可以访问 |
protected | 给子类访问 |
默认权限(不写) | 在同一个包中可以访问 |
其他修饰符 | 作用 |
---|---|
abstract | 修饰类(抽象类)和方法(抽象方法) |
static | 被类名访问 |
final | 修饰类不能被继承,修饰方法不能被复写,修饰变量不能被修改 |