面向对象
小笔记
-
调用内部属性 对象.属性名
-
调用方法 对象.方法名
-
调用非静态方法 先new 再调用
-
不可改动的,静态static是类的,final是固定的,private私有的
快捷键
- 1.ALT+Insert(在功能区)
- 可快速生成set/get/构造器
- 2.Ctrl+H(在功能区)
- 查看类关系
this关键字
- 表示本类中的属性
- 可供类内部调用
构造器
- new的过程其实就是调用了类的构造器
- new对象就是实例化
- 无参构造是默认存在的
- 在写重载方法时,必须在类里添加无参构造(不然会报错)!!!
public class Person {
String name;
int age;
//添加构造器 无参构造
//new的本质就是调用构造器方法
public Person() {
this.name = "name";
}
//一旦定义了无参构造,就必须(写)显示无参定义!!!!!
public Person(String name) {
// this.name代表类里String name;
//name代表调用对象时传入的内容
this.name = name;
}
public Person(int age) {
this.age = age;
}
/*
//new 实例化对象
Person person = new Person();
System.out.println(person.name);
*/
}
//学生类
public class Student {
//定义属性
//调用 对象名.name=...
String name;//赋值操作 new 对象后
int age;
//方法
public void say(){
//this表示类里面的变量
System.out.println(this.name+"在说话");
}
public int getAge(){
return this.age;
}
/*
//new_对象,就是实例化
Student student = new Student();
student.name="小明";//这里就是定义属性
student.age=18;
student.say();
System.out.println(student.getAge());
//这里就是定义属性
*/
}
封装
- *属性私有,get/set
- 添加了private范围修饰符
- 私有化后外部无法调用
- 封装意义:
- 提高安全性,保护数据
- 隐藏代码实现细节
- 统一接口
- 系统可维护性
public class Student {
//封装
private String name;//外部不可调用
private int age;
public int 测试属性;//外部可直接调用
//获取属性值
public int getId() {
return id;
}
//设置属性值
public void setId(int id) {
this.id = id;
}
private int id;
private char sex;
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
//这里防止不合实际
if (age > 120 || age < 0) {//避免非法内容
this.age = 3;//如果非法输入,则返回3
}
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
Student student = new Student();
//private后 student.name="XingChenBeiTian";
//不能被用户调用,只能通过set,get方法调用
student.setName("XingChenBeiTian");
System.out.println(student.getName());
*/
}
继承(extends)
-
子类可获得父类方法,同时子类还可以写自己的方法
-
父类
//每个类都默认继承Object public class Person /*extends Object*/ { //定义一个课程进度 //外部无法使用 private double CourseProgress = 0.85; //set/get方便外部调用 public double getCourseProGress() { return CourseProgress; } public void setCourseProGress(double courseProgress) { CourseProgress = courseProgress; } public void say(){ System.out.println("星辰北天,java学习小白"); } }
-
子类
public class Student extends Person{ //新的方法,和父类不同 //子类可以用父类public方法和变量属性 public void tell(){ System.out.println("新方法"); } }
super关键字
-
注意点
- super调用父类构造方法,必须在构造方法中的第一个
- super必须只能出现在子类的方法或者方法中!!!!
- super和this不能同时调用构造方法
-
VS this:
-
代表对象不同
- this 本身调用对象
- super 父类对象应用
-
前提
- this 没有继承也可用
- super 只能在继承类中用
-
构造方法
- this(); 本类的构造
- super; 福利地构造
//这是父类
public class Father {
protected String name="XingChenBeiTian";
public Father() {
System.out.println("父类构造");
}
}
//===========================================
//这是子类
public class Son extends Father{
protected String name = "星辰北天";
//添加构造器
public Son() {
//写super();//必须放第一位
super();//这个时默认的可以不写
// this();//两个不能同时写
System.out.println("子类构造");
}
//引用父类
public void say(String name) {
System.out.println(name);//方法传入
System.out.println(this.name);//本类调用
System.out.println(super.name);//父类调用
}
}
/*
//函数入口
public static void main(String[] args) {
Son son = new Son();
son.say("java小白");
}
*/
重写(override)
-
重写只是方法的重写与属性无关
-
重写子类(((方法名必须与父类相同))),方法体不同!!!
-
修饰符范围可以扩大但不能缩小
public>protected>Default>proviate
-
否则会抛出异常,ClassNotFoundException–》Exception(大)
-
使用前提(为什么重写)
-
父类的方法满足不了使用,子类一定1需要,父类不一定需要
//父类
//重写只是方法的重写与属性无关
public class B {
public void say(){
System.out.println("B父类:test");
}
public static void tell(){
System.out.println("静态B");
}
}
//=============================================================
//子类继承
public class A extends B{
@Override
public void say() {
System.out.println("子类:Atest");
}
public static void tell(){
System.out.println("静态A");
}
}
//===================================================================
//函数入口
public static void main(String[] args) {
/*
静态的重写方法属于重载,可以理解为类的方法,静态不能重写
非静态的方法重写,可以理解为对象的方法
下面的,左边是属于类的,引用的方法也都是类的方法
右边是new出来的对象
B b = new A();
*/
A a=new A();//子类A
//父类的引用指向了子类,多态
B b = new A();//父类B
a.tell();//静态调用
a.say();
b.tell();//静态方法
}
个人
-
静态的重写方法可以理解为重载,是类的方法,静态不能(不算,因为调用的都是自己类的方法)重写
-
非静态的方法重写,可以理解为对象的方法
下面的,左边(B)是属于类的,引用的方法也都是类的方法
右边是new出来的对象
B b = new A(); -
ALT+Insert
-
非静态的是重写
-
静态的不是
多态(instanceof判断是否有关系)
-
方法的多态
-
有继承关系
-
父类可以指向子类,但不能调用子类的方法
-
Person person=new Son(); ((Son)person).tell();//tell子类方法,父类Person调用只能强转
-
代码还是上面的改动
-
实例
-
//父类
public class B {
public void say(){
System.out.println(“B父类:test”);
}
}
//=============================================================
//子类继承
public class A extends B{
@Override
//重写
public void say() {
System.out.println(“子类:Atest”);
}
//多态的
public static void tell(){
System.out.println(“静态A”);
}
}
//===================================================================
//函数入口
public static void main(String[] args) {
A a=new A();//子类A
//父类的引用指向了子类,多态
B b = new A();//父类B
a.say();
b.tell();//静态方法
((A)b).tell();//强转调用子类方法
System.out.println(A instanceof B);//判断是否有关系
System.out.println(Object instanceof B);//判断是否有关系
//同层不可比较
}
> 个人
- 调用的类方法只与**(=)**前有关,与后面的关系不大!!!!!!!
- 必须**(关系)**类,方法需要重写,父类调用子类方法要强转(父类指向子类)
```java
((子类)父类).子类方法();//强转调用子类方法
- 类转换异常ClassCastException
//高 低
父类 a = new 子类();
((子类) a).子类方法();
//低 高
子类 obj =new 子类();
父类 b = obj;
b.子类方法();
/*父类引用指向子类对象
*高----低 向下转换,强制转换,会丢方法
*低----高 向上转换,直接转换
* 作用:简化代码,提高利用率
* */
代码块,static和final
- 就直接代码演示了
public final class 父类 {
//如果类被final修饰后子类就不能继承了(断子绝孙了--_--)
{//2
System.out.println("匿名代码块");
}
static {//1,只能执行一次,可用来赋初始值
System.out.println("静态代码块");
}
public 父类() {//3
System.out.println("构造方法");
}
public static void main(String[] args) {
父类 x = new 父类();
System.out.println("=========");
父类 x2 =new 父类();
}
}
个人
- 代码块在构造器之前执行(可匿名)
- static静态代码块每个类只能加载一次(可用来赋初始值)
- final(常量)修饰的类不能被继承
静态导入包(节省使用一次的代码)
//静态导入包
import static java.lang.Math.random;//随机数
import static java.lang.Math.PI;//圆周率
public class Test {
public static void main(String[] args) {
//可以不写成Math.random的形式
System.out.println(random());
System.out.println(PI);
}
个人
- 直接看代码就OK
抽象(abstract)
- 父类
//abstract抽象类,extends单继承 子类继承需要实现方法,除非子类也是abstract类 (接口可多继承)
public abstract class 抽象 {
//java有约束,需要别人来实现
//abstract抽象只有方法,没有方法的实现
public abstract void 抽象方法名();
//不能new
//抽象类中可以写正常方法
//抽象方法必须再抽象类里
- 子类
public class 子类 extends 抽象 {
@Override
public void 抽象方法名() {
//这里实现抽象方法
}
个人
- 直接看代码就OK
接口的定义与实现
- 接口定义
- 接口1
//关键字interface,接口类都需要有实现类
public interface 接口1 {
//常量~public final
int 年龄 = 18;
//接口中定义的方法其实都是public abstract
public abstract void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
- 接口2
public interface 接口2 {
void say(String name);
}
- 实现类
//需要导包
//实现接口方法,关键字implements 接口可多继承(接口1,接口2)
public class 实现类 implements 接口1, 接口2 {
//接口1方法
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
//接口2方法
@Override
public void say(String name) {
}
}
个人
- 没有构造器,不能new,实现类需要重写(所有接口方法)
- java常用的开发模式
- 别人写接口,我们实现对应方法
- 很关键,也很抽象
内部类
- 成员内部类
//外部类
public class 成员内部类 {
private int id = 10;
public 成员内部类() {
System.out.println("外部类");
}
//成员内部类
class Inner {
public void in() {
System.out.println("成员内部类");
}
//可以调用外部变量
public int getId() {
return id;
}
}
}
-
调用
public static void main(String[] args) { 成员内部类 outer =new 成员内部类(); 成员内部类.Inner inner = outer.new Inner(); inner.in(); System.out.println(inner.getId()); }
-
局部内部类
public class 局部内部类 {
public void in() {
class 局部内部{
//这里写方法
}
}
}
个人
- 接口可以new
- 但要实现接口所有的方法
//new接口
接口1 user1=new 接口1(){
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
};