1.编程思想
1.面向过程
- 步骤清晰,简单,按步骤去完成;
- 面向过程适合处理一些较为简单的问题;
2.面向对象
- 分类、抽象的思维,先去考虑解决问题需要哪些分类,然后对单个分类进行具体实现,对具体的细节通过面向过程方式实现;
- 面向对象适合处理复杂的问题,适合处理需要多人协助的问题;
解决问题的思路:
- 复杂的任务从整体上分析,需要使用面向对象的思路来分析整个系统,考虑需要哪些对象,再把相同类型的对象抽象成类;
- 具体的微观操作需要面向过程的思路去实现;
面向对象的本质:以类的方式组织代码,以对象的组织(封装)数据
2.面向对象特性
- 封装
- 继承
- 多态
对象创建内存分析
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name="旺财";
dog.age=3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat = new Pet();
}
}
/*
* 类是一个模板,是对象的抽象;对象是一个具体的实例;
* */
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println("旺旺");
}
}
过程解析
- 堆中方法区先生成类模板(类加载),存储静态main(),常量池中存"旺财"字符串
- new 执行时,在栈中先会生成一个Pet dog 引用类型变量,存放实例对象的内存地址,同时堆中初始化一个实例对象pet,默认初始化,然后顺序执行去给属性赋值;
- 实例对象也可以调用方法区中的静态方法,但本质上静态方法是类的级别,通过类去调用。
相关概念
- 类与对象:类是一个模板,抽象,对象是一个具体的实例;
- 方法:涉及方法定义,方法调用(静态方法、普通方法);
- 引用变量:引用类型,除基本类型之外都为引用类型,对象是通过引用来操作的;
- 属性:字段,成员变量
- 对象创建,默认调用无参构造函数进行初始化,
类型 | 默认值 |
---|---|
数字 | 0 / 0.0 |
char | u0000 |
boolean | false |
引用类型 | null |
注:除基本类型外都是引用类型,包括自定义的类
- 对象的创建和使用:
- 使用new关键字创造对象,通过构造器进行初始化,Pet pet = new Pet()
- 对象属性使用: pet.name
- 对象方法使用:pet.walk();
- 类:静态属性 ,动态行为(方法)
- 封装、继承、多态
1.封装
封装是针对属性
- 程序设计思想:“高内聚,低耦合”,高内聚是类内部数据操作细节自己完成,不允许外部干涉;低耦合,暴露少量的方法给外部使用;
- 实现方式:属性私有,通过公有的set和get方法进行调用;
- 封装意义
- 提高程序的
安全性
,对通过set方法去给属性赋值可以提前进行参数过滤和判断 - 隐藏代码的实现细节,包括参数过滤实现
- 统一接口,通过set,get前缀的方法,统一去调用类中的户型
- 提高系统可维护
- 提高程序的
/*
* 封装:属性私有,对属性进行合法性或安全校验
* */
public class Cats {
private int age;
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
//内部进行逻辑判断,提高程序的安全性
if(age<=120||age>=0){
this.age = age;
}else {
this.age = -999;
}
}
public int getAge(){
return this.age;
}
//无参构造函数
//1.使用new关键字,本质是在调用构造器
//2.用来初始化值
public Cats(){}
//有参构造,一旦定义了有参构造,无参就必须显示定义
public Cats(String name, int age){
this.name = name;
this.age = age;
}
}
public class CatTest {
public static void main(String[] args) {
Cats cat = new Cats("zc",2);
System.out.println(cat.getName()+cat.getAge());
}
}
2.继承
- 子类继承父类,对父类进行拓展,包括创建新的属性,方法以及重写父类中的方法
- java类只有单继承,没有多继承
- 私有的属性或方法不可以被子类调用
- final修饰的方法不能被继承
public class Animal {
//私有属性不能继承
public int age;
public String name;
public void setName(String name1){
this.name = name1;
}
public String getName(){
return this.name;
}
//私有方法不能被继承
private void say(){
System.out.println("Animal私有方法");
}
public void walk(){
System.out.println("动物行走");
}
public static void sign(){
System.out.println("父类的方法");
}
}
public class Dog extends Animal{
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Dog(String address) {
this.address = address;
}
//重写都是方法的重写和属性无关
@Override
public void walk() {
System.out.println("Dog行走");
}
public static void sign(){
System.out.println("子类的方法");
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Dog("家里");
animal.name = "zc";
animal.age = 2;
System.out.println(animal);
//System.out.println(animal.say());
/*
* 静态的方法和非静态的方法区别很大:
* 静态方法:方法的调用只和左边定义的数据类型有关,Dog或Animal
* 非静态方法:才会涉及到重写
* */
//静态方法重写
Dog a1 = new Dog("wcai");
a1.sign();
Animal a2 = new Dog("ss");
a2.sign();
}
}
1.super关键字:
- super调用父类的构造方法,必须在构造方法的第一个;this同理
- super 必须只能出现在子类的方法或构造方法中
- super和this不能同时调用构造方法
2.this关键字:
- 代表的对象不同:
this:本身调用这个对象
super:代表父类对象的应用 - 前提:
this 没有继承也可以使用
super 只能在继承条件下才可以使用,并且只能在子类中使用 - 构造方法:
this();本类的无参构造
super():父类的构造
3.重写:需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小 public>protected>private
- 抛出的异常:范围,可以缩小,但是不能被扩大:ClassNotFoundException -->Exception(大)
为什么需要重写
1.父类的功能,子类不一定需要或不满足需求
3.多态
动态编译,可扩展性
注意事项:
- 多态是方法的多态**,属性没有多态
- 父类和子类,有联系,否则转换异常ClassCastExcaption
- 存在关系:继承关系,方法需要重写,父类引用指向子类对象
- static方法属于类,不属于实例
- final修饰属性表示常量
- private方法
- instanceof (类型转换)引用类型,判断两对象是否是父子关系、祖父子关系等
实现:
- 父类引用指向子类对象
- 把子类转换为父类,向上转型,可能丢失方法
- 把父类转换为子类,向下转型 ,强制类型转换
意义:
方便方法的调用,减少重复的代码
public class Animal {
public int age;
public String name;
public void say(){
System.out.println("动物");
}
public void pMethod(){
System.out.println("父类特有的方法");
}
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
}
public class AnimalTest {
public static void main(String[] args) {
//父类型引用指向子类型对象
Animal a1 = new Cat(2,"zc");
a1.say();
// a1.sMethod();//父类型的引用不能调用子类中特有的方法,
((Cat) a1).sMethod();//如果要使用则需要强制类型转换,将父类型对象转成子类对象
Animal a2 = new Dog(1,"hha");
a2.say();//Dog子类未重写Animal中say方法,所以调用的是Animal中的方法
//x instanceof y x与y必须存在父子类关系,注意Object是所有类的父类
Object obj = new Cat(1,"dd");
System.out.println(obj instanceof Cat);//true
System.out.println(obj instanceof Animal);//true
System.out.println(obj instanceof Dog);//false
System.out.println("=========");
Cat cat = new Cat(1, "2");
System.out.println(cat instanceof Object);//true
System.out.println(cat instanceof Animal);//true
// System.out.println(cat instanceof Dog);
}
}
关键字static
- static修饰变量
- static修饰方法
- static修饰内部类
/*
* static修饰,变量,方法,内部类
*
* */
public class StaticUseDemo01 {
public static class Inner{
int id;
String name;
}
//
private static int age;//静态变量 多线程
private double score;//非静态变量
public void run(){}
public static void go(){
}
public static void main(String[] args) {
//静态属性和静态方法,通过类名.方式调用
//类加载过程中将静态变量,静态方法,常量存入到方法区中
int res = StaticUseDemo01.age;
StaticUseDemo01.go();
//成员变量或方法,需要初始化的对象去调用
StaticUseDemo01 useDemo01 = new StaticUseDemo01();
double score = useDemo01.score;
useDemo01.run();
//static修饰内部类
Inner inner = new Inner();
System.out.println(inner.name);
}
}
3.抽象类
特点:
- 单继承
- 不能通过new进行实例化
- 存在抽象方法或普通方法
- 子类继承抽象类,必须实现抽象方法
作用:抽象出方法,提高开发效率
/*
* 抽象类:
* 1.单继承
* 2.不能通过new进行实例化
* 3.存在抽象方法或普通方法
* 4.子类继承抽象类,必须实现抽象方法
* 优势:抽象出来,提高开发效率
* */
public abstract class Father {
//只有方法定义,没有实现细节,即抽象方法
public Father(){
}
public abstract void show();
public void print(){
System.out.println("抽象类可创建非抽象方法");
}
}
4.接口
优点:
接口中只有方法规范,进行约束和实现分离,面向接口编程
接口本质是契约
- 类可以实现接口 implements 多个接口
- 实现了接口的类,就需要重写接口中的方法
- 多继承,利用接口实现多继承
- 接口不能被实例化,接口中没有构造方法,接口中的变量为常量
5.内部类
1.成员内部类,获取外部类的私有属性,方法
2.静态内部类
2.一个java类中可以有多个class类,但是只能有一个public class
3.局部内部类:
4.匿名内部类,没有名字初始化类,不用将实例保存到变量中
public class Outer {
private int id=10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这个内部类的方法");
}
//可以获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
outer.out();
//通过这种方式实现创建内部类
Outer.Inner inner = outer.new Inner();
inner.in();
//内部类获取外部类的静态属性
inner.getID();
}
}