封装
属性+方法构成一个类
-
保证“高内聚,低耦合”,类内部数据的操作细节由自己完成,不允许外部干涉;仅暴露出少量方法给外部使用
-
属性私有,get/set方法
-
用set方法添加限制了后,再用构造器可以直接调用set方法---》this.setName(name),保证限制的全面性
-
可通过alt+insert自动生成,选择getting and setting,选择要选择的属性(多选可按住Ctrl键然后拖动鼠标)
-
作用:
有时在set里面做一些安全性的判断
继承
子类继承父类,就会拥有父类中的全部方法,以及public 的属性;私有的东西不能被继承被
所有的类,都直接或间接的继承于Object类;
Java类中只有单继承没有多继承(只能有一个人父类,可有多个子类);继承具有传递性,可以用曾祖父的方法
------>通过set/get方法来访问
super
this表示调用当前的方法,super表示调用父类的方法;
当父类与子类都有构造器时,子类会先调用父类的构造器,且super()必须在第一行,若父类是有参构造,则子类也只能显式调用父类的有参
方法的重写
注意静态static方法不能重写!!!
只有public类方法可以重写!!!下图为子类重写‘了非静态方法----->idea旁有圆点和箭头为重写标志
多态
父类
编译看左边,执行看右边。
Static关键字
【1】static可以修饰:属性,方法,代码块,内部类。
【2】static修饰属性;
package com.msb5; /**
-
@Auther: msb-zhaoss */ public class Test { //属性: int id; static int sid; //这是一个main方法,是程序的入口: public static void main(String[] args) { //创建一个Test类的具体的对象 Test t1 = new Test(); t1.id = 10; t1.sid = 10; Test t2 = new Test(); t2.id = 20; t2.sid = 20; Test t3 = new Test(); t3.id = 30; t3.sid = 30; //读取属性的值: System.out.println(t1.id); System.out.println(t2.id); System.out.println(t3.id); System.out.println(t1.sid); System.out.println(t2.sid); System.out.println(t3.sid); } } 内存分析:
一般官方的推荐访问方式:可以通过类名.属性名的方式去访问:
static修饰属性总结: (1)在类加载的时候一起加载入方法区中的静态域中 (2)先于对象存在 (3)访问方式: 对象名.属性名 类名.属性名(推荐)
static修饰属性的应用场景:某些特定的数据想要在内存*享,只有一块 --》这个情况下,就可以用static修饰的属性
package com.msb5; /**
-
@Auther: msb-zhaoss */ public class MsbStudent { //属性: String name; int age; static String school; //这是一个main方法,是程序的入口: public static void main(String[] args) { MsbStudent.school = "马士兵教育"; //创建学生对象: MsbStudent s1 = new MsbStudent(); s1.name = "张三"; s1.age = 19; //s1.school = "马士兵教育"; MsbStudent s2 = new MsbStudent(); s2.name = "李四"; s2.age = 21; //s2.school = "马士兵教育"; System.out.println(s2.school); } }
属性: 静态属性 (类变量) 非静态属性(实例变量)
【3】static修饰方法;
package com.msb5; /**
-
@Auther: msb-zhaoss */ public class Demo { int id; static int sid; public void a(){ System.out.println(id); System.out.println(sid); System.out.println("------a"); } //1.static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都行 static public void b(){ //System.out.println(this.id);//4.在静态方法中不能使用this关键字 //a();//3.在静态方法中不能访问非静态的方法 //System.out.println(id);//2.在静态方法中不能访问非静态的属性 System.out.println(sid); System.out.println("------b"); } //这是一个main方法,是程序的入口: public static void main(String[] args) { //5.非静态的方法可以用对象名.方法名去调用 Demo d = new Demo(); d.a(); //6.静态的方法可以用 对象名.方法名去调用 也可以 用 类名.方法名 (推荐) Demo.b(); d.b();
} }
static方法在本类中才可以直接调用:b();
实例方法只能通过对象调用,而static修饰的类方法可以通过类名和对象调用。
权限修饰符
在构造器中,super调用父类构造器和this调用子类构造器只能存在一个,两者不能共存: 因为super修饰构造器要放在第一行,this修饰构造器也要放在第一行:
改正二选一即可:
类与类的关系
总结: 【1】面向对象的思维:找参与者,找女孩类,找男孩类 【2】体会了什么叫方法的性擦,什么叫方法的实参:
具体传入的内容 实参:
【3】类和类可以产生关系: (1)将一个类作为另一个类中的方法的形参 依赖关系 (2)将一个类作为另一个类的属性 关联关系
public class Girl { //属性: String name; double weight; Mom m /= new Mom()/; //方法: public void add(int a){//参数是基本数据类型 System.out.println(a); System.out.println(a+100); } //谈恋爱的方法: public void love(Boy b){//参数是引用数据类型Boy System.out.println("我男朋友的名字是:"+b.name+",我男朋友的年龄是:"+b.age); b.buy(); } //女孩跟妈妈聊天: public void wechat(){ m.say(); } //构造器: public Girl(String name, double weight) { this.name = name; this.weight = weight; } }
public class Boy { //属性: int age; String name; //方法: public void buy(){ System.out.println("跟我谈恋爱,我给你买买买。。。"); } //构造器: public Boy(int age, String name) { this.age = age; this.name = name; } }
public class Mom { //方法: public void say(){ System.out.println("妈妈唠唠叨叨 都是爱,听妈妈的话。。"); } }
public class Test { //这是一个main方法,是程序的入口: public static void main(String[] args) { //创建一个Boy类的具体的对象: Boy boy = new Boy(30,"鹿晗"); //创建一个Girl类的具体的对象: Girl girl = new Girl("关晓彤",100); //谈恋爱: //girl.love(boy); Boy boy2 = new Boy(35,"陈伟霆"); girl.love(boy2); //还可以跟妈妈微信聊天: girl.m = new Mom(); girl.wechat(); } }
多态
【1】多态跟属性无关,多态指的是方法的多态,而不是属性的多态。 【2】案例代入:
`public class Animal {//父类:动物: public void shout(){ System.out.println("我是小动物,我可以叫。。。"); } }
public class Cat extends Animal{ //喊叫方法: public void shout(){ System.out.println("我是小猫,可以喵喵叫"); } public void scratch(){ System.out.println("我是小猫,我可以挠人"); } }
public class Dog extends Animal{ //喊叫: public void shout(){ System.out.println("我是小狗,我可以汪汪叫"); } public void guard(){ System.out.println("我是小狗,我可以看家护院,保护我的小主人。。。"); } }
public class Pig extends Animal{ public void shout(){ System.out.println("我是小猪,我嗯嗯嗯的叫"); } public void eat(){ System.out.println("我是小猪,我爱吃东西。。"); } }
public class Girl { //跟猫玩耍: /public void play(Cat cat){ cat.shout(); }/ //跟狗玩耍: /public void play(Dog dog){ dog.shout(); }/ //跟小动物玩耍: public void play(Animal an){ an.shout(); } }
public class Test { //这是一个main方法,是程序的入口: public static void main(String[] args) { //具体的猫:--》猫的对象 //Cat c = new Cat(); //具体的小女孩:--》女孩的对象 Girl g = new Girl(); //小女孩跟猫玩: //g.play(c); //具体的狗---》狗的对象: //Dog d = new Dog(); //小女孩跟狗玩: //g.play(d); //具体的动物:--》动物的对象: //Cat c = new Cat(); //Dog d = new Dog(); Pig p = new Pig(); Animal an = p; g.play(an); } }`
【3】总结: (1)先有父类,再有子类:--》继承 先有子类,再抽取父类 ----》泛化 (2)什么是多态: 多态就是多种状态:同一个行为,不同的子类表现出来不同的形态。 多态指的就是同一个方法调用,然后由于对象不同会产生不同的行为。对象不同,调用不同的重写方法
(3)多态的好处: 为了提高代码的扩展性,符合面向对象的设计原则:开闭原则。 开闭原则:指的就是扩展是 开放的,修改是关闭的。 注意:多态可以提高扩展性,但是扩展性没有达到最好,以后我们会学习 反射
(4)多态的要素: 一,继承: Cat extends Animal ,Pig extends Animal, Dog extends Animal 二,重写:子类对父类的方法shout()重写 三, 父类引用指向子类对象:
Pig p = new Pig(); Animal an = p; 将上面的代码合为一句话: Animal an = new Pig(); =左侧:编译期的类型 =右侧:运行期的类型---------编译时以为是一个动物,结果运行的时候发现是一只小猪(子类披着父类的衣服)
Animal an = new Pig(); g.play(an); // public void play(Animal an){//Animal an = an = new Pig(); an.shout(); }
上面的代码,也是多态的一种非常常见的应用场合:父类当方法的形参,然后传入的是具体的子类的对象,
多态的应用场合二:将父类当做方法的返回值;
然后调用同一个方法,根据传入的子类的不同展现出来的效果也不同,构成了多态。
向上转型,向下转型
向上转型:
Father f = new Son();父类引用指向子类对象
向下转型:
Son son = Son(father); 为了获取子类中特有的类
源文件中只能有一个public修饰的类
final修饰符
【1】修饰变量;
public class Test { //这是一个main方法,是程序的入口: public static void main(String[] args) { //第1种情况: //final修饰一个变量,变量的值不可以改变,这个变量也变成了一个字符常量,约定俗称的规定:名字大写 final int A = 10;//final修饰基本数据类型 //A = 20; 报错:不可以修改值 //第2种情况: final Dog d = new Dog();//final修饰引用数据类型,那么地址值就不可以改变 //d = new Dog(); -->地址值不可以更改 //d对象的属性依然可以改变: d.age = 10; d.weight = 13.7; //第3种情况: final Dog d2 = new Dog(); a(d2); //第4种情况: b(d2); } public static void a(Dog d){ d = new Dog(); } public static void b(final Dog d){//d被final修饰 ,指向不可以改变 //d = new Dog(); } }
【2】修饰方法; final修饰方法,那么这个方法不可以被该类的子类重写:
【3】修饰类; final修饰类,代表没有子类,该类不可以被继承: 一旦一个类被final修饰,那么里面的方法也没有必要用final修饰了(final可以省略不写)
【4】案例:JDK提供的Math类:看源码发现: (1)使用Math类的时候无需导包,直接使用即可:
(2)Math类没有子类,不能被其他类继承了
(3)里面的属性全部被final修饰,方法也是被final修饰的,只是省略不写了 原因:子类没有必要进行重写。
(4)外界不可以创建对象: Math m = new Math();|
|
(5)发现Math类中的所有的属性,方法都被static修饰 那么不用创建对象去调用,只能通过类名.属性名 类名.方法名 去调用------->Math.reandom();
接口
【1】接口声明格式: [访问修饰符] interface 接口名 [extends 父接口1,父接口2…] { 常量定义; 方法定义; }
【2】代码:
package com.msb.test04; /**
-
1.类是类,接口是接口,它们是同一层次的概念。
-
2.接口中没有构造器
-
3.接口如何声明:interface
-
4.在JDK1.8之前,接口中只有两部分内容:
-
(1)常量:固定修饰符:public static final
-
(2)抽象方法:固定修饰符:public abstract
-
注意:修饰符可以省略不写,IDE会帮你自动补全,但是初学者建议写上,防止遗忘。 / public interface TestInterface01 { //常量: /public static final/ int NUM = 10; //抽象方法: /public abstract/ void a(); /public abstract/ void b(int num); /public abstract/ int c(String name); } interface TestInterface02{ void e(); void f(); } / 5.类和接口的关系是什么? 实现关系 类实现接口: 6.一旦实现一个接口,那么实现类要重写接口中的全部的抽象方法: 7.如果没有全部重写抽象方法,那么这个类可以变成一个抽象类。 8.java只有单继承,java还有多实现 一个类继承其他类,只能直接继承一个父类 但是实现类实现接口的话,可以实现多个接口--------》因为接口内的方法是空的,不会在子类继承时发生冲突。 9.写法:先继承 再实现:extends Person implements TestInterface01,TestInterface02 / class Student extends Person implements TestInterface01,TestInterface02 { @Override public void a() { System.out.println("---1"); } @Override public void b(int num) { System.out.println("---2"); } @Override public int c(String name) { return 100; } @Override public void e() { System.out.println("---3"); } @Override public void f() { System.out.println("---4"); } } class Test{ //这是一个main方法,是程序的入口: public static void main(String[] args) { //10.接口不能创建对象: //TestInterface02 t = new TestInterface02(); TestInterface02 t = new Student();//接口指向实现类 ---》多态*{接口作为形参,传递时传它的具体实现类 或者接口做返回值类型,返回它的具体实现类}
-
-
//11.接口中常量如何访问: System.out.println(TestInterface01.NUM); System.out.println(Student.NUM); Student s = new Student(); System.out.println(s.NUM); TestInterface01 t2 = new Student(); System.out.println(t2.NUM); } } 【3】接口的作用是什么?
定义规则,只是跟抽象类不同地方在哪?它是接口不是类。 接口定义好规则之后,实现类负责实现即可。
【4】 继承:子类对父类的继承 实现:实现类对接口的实现
手机 是不是 照相机
继承:手机 extends 照相机 “is-a”的关系,手机是一个照相机
上面的写法 不好:
实现: 手机 implements 拍照功能 “has-a”的关系,手机具备照相的能力
案例:飞机,小鸟,风筝 定义一个接口: Flyable
【5】多态的应用场合: (1)父类当做方法的形参,传入具体的子类的对象 (2)父类当做方法的返回值,返回的是具体的子类的对象 (3)接口当做方法的形参,传入具体的实现类的对象 (4)接口当做方法的返回值,返回的是具体的实现类的对象
//Compare com = new Compare();
public comparable method(){
return new Comparable();//此处为匿名类(即接口的实现类)
}
/* public Comparable method3(){* //3.匿名内部类 return new Comparable(){ @Override public int compareTo(Object o) { return 200; } };*/
【6】接口和抽象类的区别: