1. 面向对象简介
面向对象是一种编程思想 ## 1.1 与面向过程区别 - 面向过程 遇到一个问题,亲力亲为的一步步解决他(小兵),典型代表语言:c
- 面向对象
遇到一个问题,找具有解决这个问题的对象,调用这个对象的方法(老板),典型代表java
内存分配情况:
class Demo{
public static void main(String[] args){
Person person = new Person();
person.name = "张三";
person.country = "中国";
Person person2 = new Person();
person.name = "李四";
person.country = "台湾";
person.sleep();
person2.sleep();
}
}
class Person{
String name;
static String country;
public void sleep(){
System.out.println(name+"======"+country);
}
}
图片如下:
1.2. 封装工具类
- 方法都用static
- 开头写一个构造方法 private Demo(){}
1.3. 代码块
- 构造代码块
{
......
}
- 静态代码块
static{
......
}
- 特点
- 使用一个类时,这个类中的静态代码块会自动执行
- 只会执行一次,第一次使用该类,就立刻执行
- 在同一个类中,静态代码块的优先级很高,比构造方法优先,比main方法优先
1.4. 继承
1.4.1 优点
- 提供了代码的复用性
- 提高代码的课维护性
1.4.2 缺点
增加了类的耦合性
- 耦合
类与类的关系 - 内聚
自己完成某件事情的能力
1.4.3 注意事项
- 子类不能继承父类的构造方法,可以通过super去访问
- 不要为了部分功能而去继承,继承是一种关系的提现
- 子类的构造方法默认会访问父类中的空参构造方法;因为每一个构造方法的第一句默认都是 super();因为子类继承父类就是需要父类中的数据
- 如果父类有有参构造,没有空参构造;子类中还是会在构造方法中加一条super();父类不会自动产生无参构造,那么就会报错,
- 在子类手动写一个super(参数);
- 在子类无参构造写一个this(参数)来调用子类是有参构造
- this()和super()不能同时存在
1.4.4 执行过程
class Fu {
public int num = 10;
public Fu(){
System.out.println("fu");
}
}
class Zi extends Fu{
public int num = 20;
public Zi(){
System.out.println("zi");
}
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
class Test{
public static void main(String[] args){
Zi zi = new Zi();
zi.show();
}
}
class Fu1 {
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu1() {
System.out.println("构造方法Fu");
}
}
class Zi1 extends Fu1 {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi1() {
System.out.println("构造方法Zi");
}
}
class Test1{
public static void main(String[] args){
Zi1 zi1 = new Zi1();
}
}
- jvm调用了main方法,main先进栈
- 遇到new子类
- 将父类.class和子类.class分别加载进内存
- 创建对象
- 当父类.class加载进累成父类的静态代码块会随着父类.class一起加载
- 子类静态代码块会随着子类.class一起加载进内存
- 开始走子类的构造方法,因为java中是分层初始化的,先初始化父类,再初始化子类,所以先走父类
- 父类初始化结束,子类开始初始化
1.5 接口与抽象类
1.5.1 相同点
- 都不能创建对象
- 都是作为父类/接口
- 子类/实现都必须重写方法,然后才能创建对象
1.5.2 不同点
- 抽象类用关键字abstract接口用关键字interface
- 抽象类中可以有抽象方法,可以没有抽象方法,也可以部分是抽象方法
- 接口中只有方法,都必须是抽象的
- 抽象类可以定义任意成员变量,接口的成员变量必须加上public static final修饰
- 类和抽象类之间的关系是单继承,类和接口的关系是多实现
- 思想上的区别
- 抽象类中必须定义整个继承体系的共性内容
- 接口中定义整个继承体系同之外的额外的扩展的功能
- 抽象类为部分方法提供实现,避免了子类重复实现这些方法,提高代码重用性
抽象类为继承体系中的共性内容,接口为继承体系外的扩展功能
1.5.3 二者选用
- 优先选用接口,尽量少使用抽象类
- 需要定义子类的行为,又要为子类提供共性功能时才轩选用抽象类
1.5.4 多态
- 前提
- 必须有子父类关系(必须有继承)
- 必须有方法的重写
- 表现形式
父类类型 变量名 = new 子类类型(); - 注意事件
- 成员变量编译和运行都是使用的父类的
- 成员方法编译时看父类,运行时看子类
- 缺点
多台只能调用子父类共有的方法,不能调用子类特有的方法 - 优点 提高了程序的灵活性
- 父类类型的变量可以接受任何一个子类的对象
- 编译时看父类,运行时看子类
- 解决不能调用子类特有方法
向上向下转型 - 强制转换
- instanceof运算符 可以判断是不是某个类型
1.5.5 匿名内部类
- 作用
快速创建抽象类的子类对象,接口实现类对象
利用内部类快速创建抽象类的子类
public abstract class AbstractAnimal {
public abstract void eat();
public abstract void speeack();
}
public static void absTest(){
Dog dog = new Dog();
dog.eat();
dog.speeack();
new AbstractAnimal(){
@Override
public void eat() {
System.out.println("不好吃");
}
@Override
public void speeack() {
System.out.println("哈哈哈");
}
};
//匿名内部类
new AbstractAnimal(){
@Override
public void eat() {
System.out.println("不好吃");
}
@Override
public void speeack() {
System.out.println("哈哈哈");
}
}.eat();
//利用多态 父类对象接受子类对象
AbstractAnimal absAnimal = new AbstractAnimal() {
@Override
public void eat() {
System.out.println("一般般");
}
@Override
public void speeack() {
System.out.println("对的");
}
};
absAnimal.eat();
absAnimal.speeack();
}
利用内部类快速创建接口的子类
public interface NuNi {
void cook();
void daoShui();
void moMo();
}
public static void infTest(){
new NuNi(){
@Override
public void cook() {
}
@Override
public void daoShui() {
}
@Override
public void moMo() {
}
};
new NuNi(){
@Override
public void cook() {
}
@Override
public void daoShui() {
}
@Override
public void moMo() {
}
}.cook();
NuNi nn = new NuNi() {
@Override
public void cook() {
}
@Override
public void daoShui() {
}
@Override
public void moMo() {
}
};
nn.cook();
nn.daoShui();
nn.moMo();
}
1.5.6 内部接口
public interface InternalInterface {
void showOut();
interface InInterface{
void showIn();
}
}
class InfDemo implements InternalInterface{
@Override
public void showOut() {
}
}
class Inf2Demo implements InternalInterface.InInterface{
@Override
public void showIn() {
}
}
1.5.7 内部类
public class InternalClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
class IntClass{
private String age;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
}
class IntClassDemo extends InternalClass{
}
class Int1ClassDemo extends InternalClass.IntClass {
}
1.5.8 static
- 存在方法区中的静态区,只有一个空间
- 静态是优先于对象存在的
- 如何访问static成员
- 对象名.静态成员;//不建议
- 类名.静态成员;//建议
1.5.9 finally
- final修饰类:不能被继承(没有子类),但是可以是其他类的子类
- 修饰方法(最终方法,牛逼):子类不能重写
- 修饰成员变量
- 这个成员变量在创建对象之前必须初始化
- 只能赋值一次
- 修饰局部变量
- 基本类型
该变量只能赋值一次(常量) - 引用类型
- 改引用类型的变量的地址不能改变
- 地址指向空间中的内容可以改变
- 基本类型
历史版本
java 是一门面向对象语言
1. 万物皆为对象
什么东西都有属性(各种参数如密度如体积)也都拥有方法(可以用来干嘛)
2. 程序是对象的集合,他们通过发送消息来告诉彼此要干嘛(相当于函数的相互调用)
一个主函数来调用各种各样的对象来实现一个很大的功能
Main就相当于一个老板 他需要造一栋房子 他就调用工程师这个对象Engineer()然后工程师要给老板一个房子当然老板要付出金钱工程师才会给他造 那么Engineer()的返回值就是房子 需要传入的就是钱
So
House Engineer(int monye){
House house = new House();
干嘛干嘛;
干嘛干嘛;
Return house;
}
然后你会发现上面黄色的地方没有定义这个House属性
那么你得要有House 这么一个对象里面有各种属性
平时看到的这种函数前面的有一个修饰符比如public private protected 一般方法用public属性用private
然后 干嘛干嘛就是工程师可以找到什么水电工什么什么工(各种对象)通过传入值告诉他们要干嘛返回值就是需要得到什么
3. 每个对象的拥有类型
就是每个对象他都有返回值 如上的例子 返回值就是一个房子 房子为你自己定义的对象 或者也可以返回基本类型 也可以返回封装类型
基本类型:boolean char byte short int long float double void
封装类型:Boolean Character Byte Short Integer Long Float DoubleVoid String
封装类型是java帮你给封装的 然后你自己也可以进行封装 其实就是新建一个class然后里面有属性有方法 你这个class的文件名就是你封装的类型名你就可以指定传入这个类型的数据也可以指定返回这个类型的数据
对象
对象的引用操作
就比如 String s = “aaa”;
那么s就是遥控器 “aaa”就是电视机
可以通过s找到aaa
如果你之前定义了一个User如
public class User{
private String name;
private String age;
public void write(){
System.out.println("写作业");
}
public void play(){
System.out.println("我在玩");
}
}
然后你在这个工程的别的地方 吧这个User实例化
User user = new User();
在这里 你可以通过user这个遥控器找到你实力化的User里面的各个公开方法
如 user.write();
如 user.play();
对象的作用域
你写在 class里面那么整个class都可以用相当于c 里面的全局变量
如果你写在函数里面那么外面就不可以用
如果你在class里面写了然后你又在函数里面写了那么在你写的函数里面使用的是你函数里面定义的 然后你在class里面定义的不会发生变化
方法参数返回值
之前修房子的例子里面提到了 一个方法如果需要有返回值那么就写返回值的类型如
Public String aaa(){}
PublicUser bbb(){}
然后参数的话就是
PublicString aaa(User user){}
PublicUser bbb(int a){}
这里的User是你自己定义的对象
Static
一个对象创建的时候其实是没有被实例化的有就是说他不是实际存在的,只有当你new这个对象(实例化)的时候才会被分配空间 也就是这个对象只是一个模板 你new的时候就是照着你的这个模板在内存中实例化
如这个对象你用的Static 那么来说他就是在你创建的时候就进行了实例化(实际分配了内存)然后你也就无需new 就可以直接调用
packagetest;
publicclass Test5 {
public void write() {
String name = "Dava";
System.out.println("我在写字" + "我的名字是:" + name);
}
public void age() {
write();
// 这里没有进行实例化却可以调用因为是
// 都是没有被实例化只不过是相对的调用了
System.out.println("我的年龄是20");
}
public static void tel(){
System.out.println("我的电话是1767****810");
}
public static void main(String[] args) {
tel();
//age();//报错
//write();//报错
Test5 t = new Test5();
t.age();
t.wait();
}
}
哈哈第一次写博客