面向对象
Java 是面向对象的编程语言,对象就是面向对象程序设计的核心 那问题来了 什么是对象?(这问题问的好)
- 你家猫 你家狗 你家桌子 你家的所有东西都可以称为对象 现实世界的一切 人 动物 皆为 “对象”
类与对象:
- 类:是一种分类 他描述一类对象的行为和状态 特征。具有相同特性与行为的事物集合
- 对象:一个个性产物,是一个个体的特征,是类的一个实例 有状态和行为
面向对象的三大核心特性:
封装:对外部不可见
- 属性的封装、方法的封装、类的封装、组件的封装、模块化封装、系统级封装…
- 模块化、信息隐藏、复用、具有安全性
继承:扩展类的功能
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
多态:方法的重载 对象的多态性
- 编译看左边 运行看右边
- 提高了代码的复用性(由继承保证)
- 提高了代码的扩展性(由多态来保证)
面向对象的创建和使用
public class Student {
String name;
int age;
public void add(){
System.out.println(this.name + "在学习");
}
}public class Application {
public static void main(String[] args) {
Student s = new Student(); //s = this
s.age = 18;
s.name = "张三";
s.add();
Student s1 = new Student(); //s1 = this
s1.age = 15;
s1.name = "李四";
s1.add();
//this = 当前对象
System.out.println(s == s1); //false 内存地址不相同 好比是张三在学习 李四在学习 不是同一个人在学习
}
}- this表示当前类中的对象
成员变量和局部变量
public class dog {
String name;
int age; //成员变量
public void show(int age) { //局部变量
age++;
System.out.println(age);
System.out.println(this.age); //输出的是成员变量 因为加了this
}
}public class Demo {
public static void main(String[] args) {
dog dog = new dog();
dog.show(10);
//输出的是局部变量的值 输出11 0
dog.age = 20;
dog.show(10);
//输出11 20
}
}- 成员变量:类中方法外、堆内存、有初始值、随着对象存在而存在消失而消失
- 局部变量:方法内、栈内存、无初始值、随着方法而存在 消失而消失
构造方法
public class Student {
String name;
int age;
public Student() {
System.out.println("实例化的时候默认提供无参构造方法");
}
public Student(String name, int age) {
this.name = name;
this.age = age;
System.out.println(name + age);
}
}public class Application {
public static void main(String[] args) {
new Student(); //实例化的时候默认提供无参构造方法
new Student("张三",15); //张三15
}
}- 如果在学生类里面先定义了有参数的构造方法 不定义无参数的构造方法 在测试调用的时候无参构造方法无法调用
面向对象封装
public class Student {
//封装 属性私有化
private String name;
private int age;
//提供无参和有参数的构造方法
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//属性私有化以后提供get 和set方法
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 class Application {
public static void main(String[] args) {
Student student = new Student();
student.setName("张三");
student.setAge(15);
System.out.println(student.getName());
System.out.println(student.getAge());
}
}- 创建的时候 属性私有化 创建set和get方法进行访问
- 属性封装完成后 访问会比较安全
面向对象继承
public class Student extends Person{}public class Person {
private String name;
private int age;
public void eat(){
System.out.println(name + "在吃东西");
}
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 class Application {
public static void main(String[] args) {
Student student = new Student();
student.setAge(18);
student.setName("张三");
student.eat();
//Student继承person以后就可以拿到eat的方法
// person属性是私有化 需要提供set和get方法才能供Student使用
}
}- 继承就相当于儿子继承爸爸、 父子类、猫、狗 继承动物等等
- 可以单继承 不可以多继承(一个爸爸有多个儿子) 可以多重继承(儿子继承爸爸、爸爸继承爷爷) 祖传三代 B继承A C继承B等
- Object是老祖宗类、在java当中所有的类都间接继承Object类
super关键字
public class Student extends Person{
String name = "Student";
public Student() {
System.out.println("Student无参执行.");
}
public void add(String name){
System.out.println(name); //张三
System.out.println(this.name); //Student
System.out.println(super.name); //Person
}
}public class Person {
String name = "Person";
public Person() {
System.out.println("Person无参构造执行.");
}
}public class Application {
public static void main(String[] args) {
Student student = new Student();
student.add("张三");
//Person无参构造执行.
//Student无参执行.
//张三
//Student
//Person
}
}- this 没有继承也可以使用
- super 只能在继承的条件下使用 只能出现在子类的方法 构造器中
- super和this不能同时调用构造方法
抽象类
//抽象类
public abstract class Animal {
//抽象方法
public abstract void test();
public void add(){
System.out.println("成员方法");
}
}- 不能实例化
- 抽象类 可以写普通方法 抽象方法必须在抽象类中
- 有抽象方法的类必须是抽象类 抽象方法没有方法体
- 约束
- 抽象方法必须在子类中被实现 除非子类是抽象类
- 把公共的东西抽象出来 提高开发效率 供子类使用
public abstract class Animal {
//抽象方法
public abstract void eat();
public abstract void sleep();
}public class dog extends Animal{
String name;
@Override
public void eat() {
System.out.println(name +"吃饭");
}
@Override
public void sleep() {
System.out.println(name + "睡觉");
}
}public class Demo {
public static void main(String[] args) {
dog d = new dog();
d.name = "小狗";
d.eat(); //小狗吃饭
d.sleep(); //小狗睡觉
}
}- dog继承Animal抽象类 那dog每天必须要做的事情就是吃饭和睡觉 把公共的东西抽象出来 提高开发效率 供子类使用
面向对象多态
实现思路
- 继承
- 子类重写父类
- 父类引用指向子类
访问方式
- 成员变量:编译看左边 (父类) 运行看左边(父类)
- 方法:编译看左边(子类) 运行看右边(子类)
public class Cat extends Animal{
public void eat(){
System.out.println("小猫在吃猫粮");
}
public void sleep(){
System.out.println("小猫在睡觉");
}
}public class Animal {
public void eat(){
System.out.println("动物在吃饭");
}
}public class Test {
public static void main(String[] args) {
//向上转型
Animal a = new Cat();
//只能调用吃的方法 不能调用子类睡觉的方法
a.eat(); //小猫在吃猫粮
//向下转型 需要向上转型后才能使用向下转型
Cat c = (Cat) a;
//调用子类睡觉的方法
c.sleep(); //小猫在睡觉
}
}- 成员变量:编译看左边 (父类) 运行看左边(父类)
- 方法:编译看左边(子类) 运行看右边(子类)
instanceof运算符
- 判断引用指向的对象类型
public class Cat extends Animal{
public void eat(){
System.out.println("小猫在猫粮");
}
public void sleep(){
System.out.println("小猫在睡觉");
}
}public class Dog extends Animal{
@Override
public void eat() {
System.out.println("小狗在吃饭");
}
public void sleep(){
System.out.println("小狗在睡觉");
}
}public class Animal {
public void eat(){
System.out.println("动物在吃饭");
}
}public class Test {
public static void main(String[] args) {
//向上转型
add(new Cat()); //小猫在猫粮
add(new Dog()); //小狗在吃饭
System.out.println("===================");
//向下转型
show(new Cat()); //小猫在睡觉
show(new Dog()); //小狗在睡觉
}
public static void add(Animal animal){
animal.eat();
}
/*
* 当在调用这个方法的时候 判断传入的参数
* 如果是Cat 则会判断animal是否是指向Cat
* 如果指向Cat就进行向下转型
*/
//微妙之处:通过instanceof进行判断更加方便
public static void show(Animal animal){
if (animal instanceof Cat) {
Cat c = (Cat) animal;
c.sleep();
} else if (animal instanceof Dog) {
Dog d = (Dog) animal;
d.sleep();
}
}
}接口
什么是接口
- 一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口的特点
- 接口中的每个方法都是隐式抽象的,接口中的方法会被隐式的指定为public abstract
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final变量
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法
接口和类的区别
- 接口不能实例化
- 接口没有构造方法
- 接口中所有的方法必须是抽象方法,java8之后可以使用default关键字修饰非抽象方法
- 接口不能包含成员变量,除了static和final变量
- 接口支持多实现
接口和抽象类的区别
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不能有方法体
- 抽象类中的成员变量可以使各种类型的,而接口中的成员变量只能是public static final类型的。
- 接口中不能含有静态代码块以及静态方法,而抽象类中可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类可以实现多个接口。
public interface caidan {
//无法实例化
//都是抽象方法
void jiaozi();
void miantiao();
}//厨师类实现了这个接口要做不同的饭
public class chushi implements caidan{
@Override
public void jiaozi() {
System.out.println("韭菜鸡蛋");
}
@Override
public void miantiao() {
System.out.println("西红柿面条");
}
}public class Demo {
public static void main(String[] args) {
chushi c = new chushi();
c.jiaozi(); //韭菜鸡蛋
c.miantiao(); //西红柿面条
}
}常量
- final 必须手动赋值;
- final 修饰的类无法被继承;
- final 修饰的方法无法被覆盖;
- static final 联合使用为常量
public class FinalTest {
public static void main(String[] args) {
System.out.println(user.Guo_ji);
System.out.println(user.age);
System.out.println(user.name);
}
}
final class user{
static final String Guo_ji = "中国"; //常量
public static final int age = 15; //公开常量
static String name = "张三";//静态
}访问控制权限
| 访问权限 | 同类 | 同包 | 非同包子类 | 非同包非子类 |
|---|---|---|---|---|
| √ | √ | √ | √ | √ |
| √ | √ | √ | √ | × |
| √ | √ | × | × | × |
| √ | × | × | × | × |