Java面向对象

思想概述

面向过程

面向过程,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。

  • 例如:吃煎饼果子利用面向过程的思想:
  1. 学习摊煎饼的技术
  2. 买材料鸡蛋,油,葱等等
  3. 开始摊
  4. 收拾

特点

  • 强调的是过程,所有事情都需要自己完成
  • 代表语言:C语言

面向对象

面向对象思想就是不断的创建对象,使用对象,指挥对象做事情。(如果有对象,直接用对象,对我们直接提供服务)

  • 例如:吃煎饼果子利用面向对象的思想
  1. 找会摊煎饼的大妈(创建一个摊煎饼大妈的对象)
  2. 调用其摊煎饼的技能(功能),传递进去钱参数
  3. 返回给我们一个煎饼

特点

  • 强调的是对象,然后由对象去调用功能
  • 面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分
  • 适合解决规模较大的问题

类和对象

概述

Java中最基本的单位是类,类和对象是用来描述现实世界的事物的:
属性 :就是该事物的描述信息(事物身上的名词)
行为 :就是该事物能够做什么(事物身上的动词)

类和对象的关系

  • 类是构造对象的模板和蓝图,可以将类想像成制作小甜饼的模具,而对象是小甜饼
  • 类是相对于具体事物的抽象概括
  • 由类构造对象称为:创建类的实例

(例如:车是一个类,具体的开的奔驰、宝马,就是对象)


类是一组相关的属性和行为的集合
(例如:我们班所有的同学都具备相同的属性和行为,比如:姓名,年龄,学习,这样就把所有的学生成为学生类)

属性:事物的属性特征用成员变量来定义
意味着当调用方法时,对象的属性有可能会改变

行为:事物的行为用可调用的成员方法来定义
意味着可以对对象完成哪些操作,或者可以对对象应用哪些方法

对象
是该类事物的具体体现
(例如:某个具体的学生)

类的定义

其实就是定义类的成员(成员变量,成员方法和构造器)

成员变量

表示事物的属性

位置:在类中,方法外
有默认值,不需要进行初始化也可以使用
例如

  •  double salary;
     String name;
    

成员方法

表示事物可以发生的行为

例如:

  •   public void raiseSalary(double byPercent)
      {
      double raise = salary * byPercent / 100;
      salary += raise;
      }
    

构造方法

给创建类的实例对象时用的,用于给对象的数据进行初始化

构造方法的定义

  • 方法名与类名相同
  • 无返回值类型,连void也没有
  • 没有具体的返回值

类型
无参构造:若此时没有写构造方法,系统会自动提供无参构造方法,若已经自己写出了构造方法,系统将不再提供

  •   public Order(){ }
    

有参构造:带参数进去的初始化

  •   public Account(int number){…}
    

调用
构造器的调用其实就是利用它来创建类的实例

格式:用new关键字

  •   类名 对象名 = new 构造方法名(…);
    

注意事项

  1. 系统本身会提供构造方法,但是是无参构造方法
  2. 如果已经写出了构造方法,系统将不再提供默认的无参构造方法,此时若还想使用无参的构造,必须自己提供(推荐无参和有参的都自己写)
  3. 构造方法是可以重载的(方法名相同,参数列表不同)
  4. 对于有参的构造方法,一创建对象就有相应的自己给出的初始值

封装

处理对象的一个重要概念

  • 实现类的方法不能直接访问其他类的实例字段(对象中的数据)
  • 客观世界里的成员变量都是隐藏在对象内部的,外界无法直接操作和修改
  • 外界需要通过对象的方法与对象数据进行交互(间接)

原则

  • 将不需要对外提供的内容隐藏起来
  • 把属性隐藏,提供公共方法对其访问(间接的访问方式,就不需要直接来访问成员变量了)

方法
成员变量用private修饰,提供对应的getXxx()和setXxx()方法

好处

  • 通过方法来控制成员变量的操作,提高了代码的安全性
  • 把代码用方法进行封装,提高了代码的复用性

示例
封装前:外界可以直接通过 对象名.name直接访问

  •   String name;
    

封装后:外界需要通过getName()和setName()方法来访问

  •   public String getName()
      {
      return name;
      }
    
  •   public void setName (String name)
      {
      	this.name = name;
      }
    

类的示例

内容

  • 成员变量(private)
  • 构造方法:带参和无参
  • 成员方法:getXxx()和setXxx()
  • 给成员变量赋值的方式:
    【1】无参构造+setXxx()
    【2】带参构造
public class Student {
	//成员变量
	private String name;
	private int age;
	
	//构造方法
	public Student() {}
	
	public Student(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	//成员方法
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
}

类的使用

要想使用类的成员,必须先创建一个该类的对象,并指定其初始化状态,然后对对象调用方法(其实就是要创建类的实例对象)

步骤

  1. 使用构造器创建一个类的对象
    类名 对象名 = new 类名(…);
  • 右边:new 类名(…)的动作表明通过new操作符利用构造器创建了一个新的对象
  • 左边:类名 对象名 = 的动作相当于把右边创建的对象地址存放在左边的对象变量中,这样利用对象变量就可以方便多次使用这个对象了
  1. 通过对象访问类的成员
    使用成员变量对象名.成员变量
    给成员变量赋值的方法:
    【1】直接访问成员变量赋值: staff.name = “Harry”;
    【2】通过getXxx()和setXxx()方法来给成员变量赋值:setName(“Harry”);
    【3】通过构造方法进行初始化值

    使用成员方法对象名.成员方法

示例

/*
 * 测试类
 */
public class StudentTest {
	public static void main(String[] args) {
		//无参构造方法+setXxx()
		Student s = new Student();
		s.setName("林青霞");
		s.setAge(30);
		System.out.println(s.getName()+"---"+s.getAge());
		
		//带参构造方法
		Student s2 = new Student("林青霞",30);
		System.out.println(s2.getName()+"---"+s2.getAge());
	}
}

关于类的内存图解

  1. 创建1个对象
    对象是在堆内存中创建的
  2. 创建2个对象
    两个对象变量指向两个对象
  3. 创建2个对象变量(指向同一个对象)
    对象变量拿到相同的地址

类的注意事项

  1. 定义类时候明确:成员变量和成员方法
  2. 类的使用可以通过一个测试类实现
  3. 最好用不同的类表示不同的概念
  4. 只要是某个类里面的对象,这个对象就一定符合类里面的属性和行为

成员变量和局部变量

区别

  • 在类中的位置不同
    成员变量:在类中,方法外
    局部变量:在方法中或者方法声明上(形式参数)

  • 在内存中的位置不同
    成员变量:在堆内存
    局部变量:在栈内存

  • 生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

  • 初始化值不同
    成员变量:有默认值
    局部变量:没有默认值,必须先定义,赋值,最后使用

就近原则
如果局部变量和成员变量名称一致,在方法中使用的时候采用的是就近原则

关键字和修饰符

this和super

this:指示编译器调用子类(本类)方法/构造器的特殊关键字

  • 代表所在类的对象引用,指向现在所在的本类
  • 方法被哪个对象调用,this就代表那个对象

super:指示编译器调用超类方法/构造器的特殊关键字

  • 代表超类存储空间的标识,指向本类所引用的类

用法:
访问成员变量:

  •  	this.成员变量
     	super.成员变量
    

访问构造方法:

  •  	this(...)
     	super(...)
    

访问成员方法:

  •  	this.成员方法()
     	super.成员方法()
    

final

关键字final表示最终的意思,可以修饰类,方法和变量

修饰类:表明该类是最终类,不能被继承
修饰方法:表明该类是最终方法,不能被覆盖/重写
修饰变量:表明该变量为常量,不能被再次赋值

static

静态修饰符,修饰类中的成员(成员变量和成员方法)

作用
被类的所有对象共享

特点

  • 在类中定义的
  • 随着类的加载和加载,优先于对象的创建存在
  • 用static修饰的成员可以通过类名直接访问:类名.成员

例如在Student类中,age被static修饰了,则:

  •   Student.age = 18; // 被所有Student类的对象共享
    

访问特点
非静态的成员方法:

  • 访问成员变量:静态or非静态
  • 访问成员方法:静态or非静态

静态的成员方法:

  • 访问成员变量:静态
  • 访问成员方法:静态

注意事项

  • 静态成员方法中不能出现this,super等关键字
    原因:静态成员是随着类的加载而加载的,this,super这样的关键字是随着对象的创建而存在的,先进内存的,不能访问后进内存的

  • 判断一个成员是否用static修饰,则看这个成员是否需要被类的所有对象共享

权限修饰符

类型
在这里插入图片描述

归纳

  • 要想仅能在本类中访问使用private修饰
  • 要想本包中的类都可以访问除了private修饰符,其它都可以
  • 要想本包中的类与其他包中的子类可以访问使用protected修饰
  • 要想所有包中的所有类都可以访问使用public修饰。

继承

Java程序设计中的一项核心技术
类和类之间关系的一种:继承
明显特征:“is-a”(是 关系)

基本思想

  • 可以基于已有的类创建新的类,继承已存在的类就是复用(继承)这些类的方法,而且可以增加一些新的方法和字段,使新类能够适应新的情况。
  • 多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需在定义这些属性和行为,只要继承那个类即可
  • 有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员
    单独的这个类称为父类,基类或者叫超类,多个类可以称为子类或者派生类

概念

被继承的类:超类(superclass),基类(base class),父类(parent class)
继承的新类:子类(subclass),派生类(derived class),孩子类(child class)

定义

用extends关键字
格式

  •   public class 子类名 extends 父类名{}
    

例子

  •   public class Manager extends Employee
      {
      	added methods and fields
      }
    

注意

  • 通过扩展超类来定义子类的时候,只需要指出子类和超类的不同之处
  • 设计类的时候,将最一般的方法放到超类中,而更特殊的方法放到子类中
  • 这种将通用功能抽取到超类的做法在面向对象程序设计很普遍

好处和弊端

好处

  • 提高了代码的复用性
  • 提高了代码的维护性
  • 让类与类之间产生了关系,是多态的前提

弊端:

  • 让类与类之间产生了关系,也就让类的耦合性增强了。

继承特点

  1. Java只支持单继承,不支持多继承
  2. Java支持多级继承:
    由一个公共超类派生出来到所有类的集合成为继承层次
    从某个特定的类到其祖先的路径称为该类的继承链
  3. Object类是类层次结构的根类/超类,所有的类都间接或直接的继承自该类

成员特点

成员变量

成员变量名称不一样:直接区分
成员变量名称一样的情况:就近原则

在子类中访问变量:方法–子类–超类–报错
• 在方法的局部范围找,如果有就使用
• 在子类的成员范围找,如果有就使用
• 在超类的成员范围找,如果有就使用
• 如果还找不到 就报错

成员方法

子类中方法和超类中方法的声明不一样:直接区分
子类中方法和超类中方法的声明一样:执行的是子类中的方法 就近原则

通过子类对象调用方法:子类–超类–报错

  • 在子类中找,有就使用
  • 在超类中找,有就使用
  • 如果没有就报错

构造方法

特点
子类构造方法执行前都会先执行父类无参构造方法

原因
因为子类继承父类,会继承父类的非私有成员。而子类在初始化的时候,可能会使用父类的数据,如果父类数据没有先初始化,子类就不能使用这些数据,所以,在子类初始化之前,一定要先完成父类数据的初始化。
注意:在子类的构造方法中,默认第一行有一条语句:super()

做法
可以利用super语法调用父类的构造器:super(…);

注意事项

  • 使用super调用构造器的语句必须是子类构造器的第一条语句
  • 若子类的构造器没有显示的调用超类的构造器,系统将自动的调用超类的无参构造器
  • 即系统默认:子类构造器的第一条语句为:super();
  • 若想要调用有参的构造方法,需要自己提供

示例

public class Manager extends Employee {
	//构造器
	public Manager() {
		//super();
	}
	
	public Manager(String name) {
		//super();
		super("Harry"); //调用有参的构造方法要自己提供
	}

}

方法覆盖

概述
子类中出现了和超类中一摸一样的方法声明的情况,此时访问子类方法的时候,会按照就近原则使用子类的方法

应用

  • 当子类需要超类的功能,而功能主体子类有自己特有的内容时,可以重写超类中的方法,这样既沿袭了超类的功能,又定义了子类特有的内容
  • super关键词来访问超类的非私有方法

注解
表明该方法的重写超类的方法

  •   @Override 
    

注意事项
超类中私有方法和最终方法不能被重写
子类重写超类方法时,访问权限不能更低(建议访问权限一摸一样)

  •   private--默认--protected--public
    

示例
定义一个Phone class是超类

public class Phone {
	public void call(String name) {
		System.out.println("给"+name+"打电话");
	}
}

定义一个NewPhone class是子类,重写Phone中的call方法,这样既可以保留Phone中的call方法的功能,又能增加NewPhone自己特有的功能

public class NewPhone extends Phone {
	
	@Override
	public void call(String name) {
		System.out.println("开启视频功能");
		//System.out.println("给"+name+"打电话");
		super.call(name); //直接通过super语法代表超类
	}
}

测试类


public class PhoneTest {
	public static void main(String[] args) {
		Phone p = new Phone();
		p.call("Harry");
		System.out.println("-----------");
		NewPhone np = new NewPhone();
		np.call("Harry");
	}
}

多态

概述

多态
同一个对象,在不同时刻体现出来的不同状态
在Java程序设计语言中,对象变量是多态的,一个超类型的变量既可以引用一个超类型的对象,也可以引用子类的任何一个子类的对象

应用
不能直接创建对象实例的时候,可以使用多态

好处
提高了程序的扩展性

弊端
不能访问子类特有功能

示例
让 class Manager继承了 class Employee:

Manager boss = new Manager();
Employee[] staff = new Employee[3];
staff[0] = boss;

此时boss和staff[0]同时引用Manager对象,实际上是一个Manager,但是编译器在这里只将staff[0]看成是一个Employee对象,意味着可以使用Employee对象的方法,但是不能使用子类Manager特有的方法

前提和体现

  • 有继承关系
  • 有方法重写
  • 有超类引用指向子类对象

形式

接口多态(最常见)
抽象类多态(比较常见)
具体类多态(几乎不用)

特性

多态中成员的访问特点
(左边表示等号左边的对象变量的类型,右边表示等号右边的对象类型)

  • 成员变量:编译看左边,执行看左边
  • 成员方法:编译看左边,执行看右边

为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而变量没有

转型

对象引用的强制类型转换

类型
向上转型:超类引用指向子类对象
向下转型:子类引用指向超类对象

使用原因
要在暂时忽略对象的实际类型之后使用对象的全部功能

语法
用()将目标类名括起来

  •   Manager boss = (Manager) staff[0];
    

注意
转型之后,类型一定要匹配

示例
定义一个超类Animal:

public class Animal {
	public void eat() {
		System.out.println("吃东西");
	}
}

定义一个子类Cat继承Animal类:

public class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}
	
	public void playGame() {
		System.out.println("猫捉迷藏");
	}
}

多态的使用测试类:

public class PolymorphicDemo {
	public static void main(String[] args) {
		//多态
		Animal a = new Cat(); //向上转型:超类指向子类
		a.eat(); //此时编译器认为a是Animal对象
		//a.playGame(); 
		//多态的弊端:无法访问子类特有方法

		Cat c = (Cat)a; //此时对象变量c和a同时指向了Cat对象
		c.eat();
		c.playGame();
	}
}

多态内存图解

Dog类和Cat类类型不匹配会出现错误

抽象类

概述

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。

定义

抽象类和抽象方法都必须用abstract修饰

格式
定义抽象类:public abstract class 类名 {}
定义抽象方法:public abstract void eat();
(抽象方法没有方法体)

示例
定义一个抽象类的Animal类

public abstract class Animal {
	/*
	public void eat() {
		System.out.println("吃东西");
	}
	*/
	
	//抽象方法
	public abstract void eat();
}
public class AnimalDemo {
	public static void main(String[] args) {
		/*
		Animal a = new Animal();
		a.eat();
		*/
		//不能直接通过抽象类创建实例,因为是抽象的
	}
}

抽象类特点

  • 抽象类不一定有抽象方法,但是有抽象方法的类一定是抽象类
  • 抽象类不能直接实例化:可以用多态的形式
  • 抽象类的子类:
    【1】要么重写/覆盖抽象类的抽象方法:意味着通过子类的实例对象来完成/实现某些具体的动作
    【2】要么子类还是一个抽象类

示例
定义一个Animal抽象类

//抽象类
public abstract class Animal {
	//抽象方法
	public abstract void eat();
	//非抽象方法
	public void sleep() {
		System.out.println("睡觉");
	}
}

定义一个抽象类的子类Cat类

public class Cat extends Animal {

	@Override
	public void eat() {
		System.out.println("猫吃鱼");
	}

}

抽象类测试:

public class AnimalDemo {
	public static void main(String[] args) {
		//创建对象
		//Animal a = new Animal();
		//按照多态的形式实例化抽象类
		Animal a = new Cat();
		a.eat(); //猫吃鱼
		a.sleep(); //睡觉
	}
}

抽象类的成员特点

成员变量
可以是变量
也可以是常量

构造方法
有构造方法,但是不能实例化
作用:用于子类访问超类数据的初始化

成员方法
可以有抽象方法:限定子类必须完成某些动作
也可以有非抽象方法:提高代码复用性

抽象类示例

定义一个抽象的老师类

public abstract class Teacher {
	private String name;
	private int age;
	
	public Teacher() {}
	
	public Teacher(String name,int age) {
		this.name = name;
		this.age = age;
	}

	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 abstract void teach();
}

定义数学老师类,继承老师类

public class MathTeacher extends Teacher {

	public MathTeacher() {}
	
	public MathTeacher(String name,int age) {
		super(name,age); //需要自己提供带参构造器
	}
	
	@Override
	public void teach() {
		System.out.println("数学老师教微积分");
	}
}

测试使用数学老师的类

public class TeacherDemo {
	public static void main(String[] args) {
		//使用的是具体的类的对象
		//MathTeacher
		
		//多态形式的测试
		Teacher t = new MathTeacher();
		t.setName("Harry");
		t.setAge(30);
		System.out.println(t.getName()+"---"+t.getAge());
		t.teach();
		System.out.println("---------------------------");
		
		t = new MathTeacher("林青霞", 30); //带参构造
		System.out.println(t.getName()+"---"+t.getAge());
		t.teach();
	}
}

接口

概述

为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现

定义

用关键词interface实现
格式:public interface 接口名 {}

使用

其实就是用类实现接口

  1. 将类声明为实现给定的接口:implements
    格式:public class 类名 implements 接口名 {}

  2. 对接口的所有方法提供具体定义和实现

示例

定义了一个跳高的接口

public interface Jumpping {
	//抽象方法
	public abstract void jump();
}

定义Cat类实现这个接口

public class Cat implements Jumpping {

	@Override
	public void jump() {
		System.out.println("猫可以跳高了");
	}
}

给出这个接口的使用测试类

public class InterfaceDemo {
	public static void main(String[] args) {
		//Jumpping j = new Jumpping();
		//接口多态的形式实例化
		Jumpping j = new Cat();
		j.jump();
	}
}

接口特点

  • 接口是抽象的,不能直接实例化:要用多态的形式–接口多态
  • 接口的实现类:要么是抽象类,要么重写接口中的所有抽象方法

接口的成员特点

成员变量
只能是常量
默认修饰符 public static final

构造方法
没有,因为接口主要是扩展功能的,而没有具体存在

成员方法
只能是抽象方法
默认修饰符 public abstract

注意

  • 接口本身不能提供什么
  • 接口绝不会有实例字段
  • Java8之前,接口不会实现方法
  • 提供实例字段和方法实现的任务应该由实现接口的那个类来完成,因此可以将接口看成是没有实例字段的抽象类

类和接口

关系

类与类
继承关系,只能单继承,但是可以多层继承

类与接口
实现关系,可以单实现,也可以多实现
还可以在继承一个类的同时实现多个接口

接口与接口
继承关系,可以单继承,也可以多继承

区别

成员区别
抽象类:变量,常量;有抽象方法,抽象方法or非抽象方法
接口:常量;抽象方法

关系区别
类与类:继承,单继承
类与接口:实现,单实现,多实现
接口与接口:继承,单继承,多继承

设计理念区别
抽象类:被继承体现的是:”is a”的关系(共性功能)
接口:被实现体现的是:”like a”的关系(扩展功能)

概述
其实就是文件夹

作用
对类进行分类管理

定义
格式:package 包名;
多级包用(.)分开即可

使用
不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能

导包格式:import 包名;

注意事项

  • package语句必须是程序的第一条可执行的代码
  • package语句在一个java文件中只能有一个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值