面向对象
对象:身边所有的物质,实体。
对象的特征:属性(用变量描述)。每个对象的每个属性都拥有特定值
行为(用方法描述,一个方法完成一个功能)
描述对象:
1.跟据对象抽象出类 写出框架 class Dog{ }
2.发现类的属性 选择需要的特征,
class Dog{
String name;
int age;
String kind;//品种
int health;
int love;
}
3.发现类的行为,功能 选择你关心的方法
public void sayHi(){
System.out.println(“*****”);
}
什么是类:具有相同属性和方法的一组对象的集合。类是模子,确定对象将会拥有的特征(属性)和行为(方法)。类是抽象的概念,仅仅是模板,比如:“人”
对象的概念:对象是一个能够看的到,摸得着的具体实体。
类是对象的类型,不同于int类型:具有方法。
类的写法:
定义一个类的步骤
1、定义类名
2、编写类的属性
3、编写类的方法
类将现实世界中的概念模拟到计算机程序中
public class 类名 {
//定义属性部分
属性1的类型 属性1;
属性2的类型 属性2;
…
属性n的类型 属性n;
//定义方法部分
方法1;
方法2;
…
方法m;
}
创建和使用对象:
类名 对象名 = new 类名();
Dog dog1=new Dog();
引用类的属性:对象名.属性
dog1.name=”吃货”;
dog1.age=2;
引用类的方法:对象名.方法名()
dog1.sayHi();
toString方法:
public String toString() {
return "Hi~ 大家好,我的名字叫"+name+",我的健康值是"+health+",我的类型是:"+kind;}
System.out.println(dog1);
深入
变量:成员变量和局部变量(方法,代码块)。
变量声明的位置决定变量作用域。
变量作用域确定可在程序中按变量名访问该变量的区域。
for(int i = 0, a = 0; i < 4; i++){
a++;
}
System.out.println ( a );a的作用域仅在for循环中 ,局部变量。
class Dog{
String name;
int age; 成员变量
String kind;//品种
int health;
int love;
}
在类里面定义的变量,是给类的对象使用的。
类里的成员变量在类里的所有地方都可以使用,在别的类里通过创建对象,. 使用。
变量的数据类型:
1.基本数据类型
2.javaAPI提供的引用类型
3.自定义类的类型(引用类型)
4.当使用引用类型时,注意初始化,及NullPointer的异常
成员变量和局部变量的区别:
作用域不同
局部变量的作用域仅限于定义它的方法
成员变量的作用域在整个类内部都是可见的
初始值不同
Java会给成员变量一个初始值
Java不会给局部变量赋予初始值
在同一个方法中,不允许有同名局部变量;在不同的方法中,可以有同名局部变量
两类变量同名时,局部变量具有更高的优先级
public class Dog {
//特点 属性
String name;
int age;
String kind;// 品种
int health;
int love;
public void sayHi(){
String name="aaa";
System.out.println("宠物的自白:");
System.out.println("Hi~ 大家好,我的名字叫"+this.name+",我的健康值是100," +"我的类型是:"+kind);
定义类的方法:
语法:访问权限 返回类型 方法名(参数列表){方法体}
public 返回值类型 方法名() {
//这里编写方法的主体
}
方法的返回值,两种情况
1.如果方法具有返回值,方法中必须使用关键字return返回该值,返回类型为该返回值的类型
2.如果方法没有返回值,返回类型为void
public class Student{
String name = "张三"; String,返回类型要匹配
public void getName(){
return name;
}
}
注意点:参数的个数可以多个,逗号隔开。方法调用时必须符合方法中参数的类型要求。
//区间查找
public int search2(int begin,int end,String name){
int result2=-1;
for(int i=begin;i
if(customers[i]!=null&&name.equals(customers[i].name)){
result2=i;
break;
}
}
return result2;
}
System.out.println("请输入开始查找的位置:");
int n1=scan.nextInt();
System.out.println("请输入结束查找的位置:");
int n2=scan.nextInt();
System.out.println("请输入学生姓名:");
String name1=scan.next();
int r1=n.search2(n1, n2, name1);
if(r1!=-1){
System.out.println("找到了");
}else{
System.out.println("没找到");
}
构造方法:创建对象时 调用的方法
特点:1.不用自己写,系统会自动生成一隐式构造方法
2.写法:没有返回结果那一项,方法名跟类名一样
3.构造方法可以有多个,可以带不同参数
4.一旦自己写了构造方法,系统将不再自动生成隐式构造方法
没有返回值类型,与
类名相同 可以指定参数
public 构造方法名( ) {
//初始化代码
}
public Dog(){
name = "吃货";
love = 0;
kind= "聪明的拉布拉多犬";
System.out.println(“执行构造方法”);
}
一个类是可以有多个构造方法.
方法的重载:指同一个类中多个方法,方法名相同,参数不同。与返回值、访问修饰符无关 。
方法重载有两种:参数类型不同的重载、参数个数不同的重载。
判断哪些属于方法重载:
1)public void study(String name){}
public void study(int hours){} 方法重载
2)public void study(String name){}
public string study(String name){} 不是
3)public void study(String name){}
public boolean study(String name, int age){} 方法重载
4)public Student(String name){}
public Student(String name, int age){} 构造函数重载
面向对象三大特征之一:封装 (安全)
封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
封装的好处:1.隐藏类的实现细节
2.只能通过规定方法访问数据
3.方便加入控制语句
4.方便修改
属性私有化
private String name;
private int age;
private String kind;// 品种
private int health;
private int love;
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setKind(String kind){
this.kind=kind;
}
public String getKind(){
return this.kind;
}
public void setAge(int age){
this.age=age;
}
public void setLove(int love){
this.love=love;
}
Dog d = new Dog();
d.health = 1000; 不合理的赋值
public void setHealth (int health) {
if (health > 100 || health < 0) {
this.health = 0;
System.out.println("健康值应该在0和100之间,默认值是0");
} else
this.health = health;
}
public class SE { 属性私有化
private String workNo;
private String name;
private char sex;
private int age;
private int popularity;
private int baseSalsry;
private int checkSalary;
//一个方法 给sex赋值
public void setSex(char sex){
If(sex!=‘男’&& sex!=‘女’){
sex=‘男’;
}else{
This.sex=sex;
}
}
//获取sex值
public char getSex(){
return this.sex;
}
public String getWorkNp(){
return this.workNo;
}
public void setWorkNp(String workNo){
this.workNo=workNo;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
}
测试类:
public class Test {
public static void main(String[] args) {
SE se=new SE();
se.setName(“爱编程”);
se.setWorkNo(“1000”);
se.setSex(‘男’);
s1.sayHi();
面向对象三大特征之二:继承 (代码复用)
为什么使用继承?
使用继承优化后:可以减少代码量,方便修改代码,方便后期的扩展。
使用继承:
父类也叫基类,子类也叫派生类。
编写父类:
public class Pet {
//公共的属性和方法
}
编写子类,继承父类: 继承的关键字extends
public class Dog extends Pet {
//子类特有的属性和方法
}
有些成员不能继承父类:
1.private成员
2.子类与父类不在同包,使用默认访问权限的成员
3.构造方法
访问修饰符protected
1.可以修饰属性和方法
2.本类、同包、子类可以访问
访问修饰符总结:
访问修饰符 | 本类 | 同包
| 子类 | 其他 |
private | √ |
|
|
|
默认(default /friendly) | √ | √ |
|
|
protected(受保护的) | √ | √ | √ |
|
public | √ | √ | √ | √ |
继承后的初始化顺序:父类属性 父类构造方法 子类属性 子类构造方法
子类访问父类成员:使用super关键字 super代表父类对象
访问父类属性:super.name;
访问父类方法:supper.sayHi();
如何在子类中调用父类的构造方法?
super();可以省略,可以被默认添加。
super(参数);
supper();关键字表示父类
当调用创建子类的对象时,默认先调用父类的无参,再调用子类的构造。
如果父类没有无参,则需要指定调用父类的有参,否则报错。
Override & overload区别:
Override 方法重写: a.子类重写父类已有的方法
b.方法名相同
c.参数相同
d.构造方法因为不能继承,所以不能重写
Overload 方法重载 a.在同一个类中
b.方法名相同
c.参数不同
抽象类:单继承
1.做父类用 2.指明特点和功能 3.不能实例化 不能new
public abstract class Dog{}
抽象方法 1.只能出现在抽象类里 2.表明一种功能 3.当前类的子类必须实现这种功能(重写方法)。
public abstract void sayHi();
当一个类继承一个类,类名报错可能的原因:
1.查看父类是不是抽象类 实现抽象方法
2.父类没有无参构造
zoo案例:
//父类
public abstract class Animal {
protected String name;
protected int leg;
public Animal(){
}
public Animal(String name,int leg){
this.name=name;
this.leg=leg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLeg() {
return leg;
}
public void setLeg(int leg) { 抽象方法
this.leg = leg;
}
public abstract String shout();
}
//Cat类
public class Cat extends Animal {
public Cat(){
}
public Cat(String name,int leg){
this.name=name;
this.leg=leg;
}
@Override
public String shout() {
return "喵喵喵";
}
}
//Duck类
public class Duck extends Animal {
public Duck(){
}
public Duck(String name,int leg){
this.name=name;
this.leg=leg;
}
@Override
public String shout() {
return "嘎嘎嘎";
}
}
//测试类
public class Test {
public static void main(String[] args) {
Cat cat=new Cat("猫咪", 4);
Duck d=new Duck("唐老鸭", 2);
System.out.println("昵称\t\t叫声\t\t腿数");
System.out.println(cat.getName()+"\t\t"+cat.shout()+"\t\t"+cat.leg);
System.out.println(d.getName()+"\t\t"+d.shout()+"\t\t"+d.leg);
}
}
面向对象三大特征之三:多态 (扩展)
什么是多态?
多态:指两个或多个属于不同类的对象,对同一个消息(方法调用)作出不同响应的能力
IS-A的应用
狗狗是一只(is a)宠物
里氏替换原则(LSP)
在一个软件系统中,子类对象可以替换所有使用的父类对象,且程序行为没有变化
表现形式两种:1.定义父类变量 实例化子类对象
People p=new ChinaPeople();
2.参数 传递子类对象给父类类型的参数
kanyisheng(Pet pet) kanyisheng(dog)
//People speakHello
ChinaPeople c=new ChinaPeople();
People p=c;
p.speakHello();
实现多态的步骤:
子类重写父类的方法
两种方式
1.创建父类变量,实例化子类对象
2.把父类类型作为参数类型,该子类及子类对象作为参数传入
运行时,根据实际创建的对象决定执行哪个方法
Master m=new Master();
m.name="mm";
Dog dog1=new Dog();
Pet p=dog1;
m.kanbing(dog1);
m.feed(dog1);
instanceof运算符
概念:该运算符用来判断一个对象是否属于一个类或者实现了一个接口,结果为true或false。
在强制类型转换之前通过instanceof运算符检查对象的真实类型,可以避免类型转换异常,从而提高代码健壮性
Vehicle v=new Bike();
((Car)v).jiayou();
ClassCastException类型转换异常
If(v instanceof Car){
((Car)v).jiayou();
}
语法:对象instranceof 类型 返回结果 boolean
静态: 关键词:static 不属于某个对象 所有对象共有一份 类名.
static表示“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
如果将属性定义为static,每个类只有一个这样静态存储区。而每一个对象对于所有的实例域却都有自己的一份拷贝。例如,假定需要给每一个雇员赋予唯一的标示码。现在给Employee类添加一个实例域id和一个静态域nextId
class employee{
private int id;
private static int nextId=1;
}
静态变量:
根据类成员变量是否是静态的进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。
两者的区别是:
对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
所以一般在需要实现以下两个功能时使用静态变量:
l1. 在对象之间共享值时
l2. 需要更方便访问变量时
静态常量
Public class Math{
public static final double PI=3.141592653;
}
静态方法:
通常静态方法可以直接通过类名调用,任何的实例也都可以调用,
因此静态方法中不能用this和super关键字,不能直接访问所属类的成员变量和成员方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。
静态代码块:
static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以放到类的内部,它不在任何的方法体内,JVM加载类时会 执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。执行顺序优先于所在类的构造方法。
final关键字
final关键字可以修饰类、方法、成员变量
final的含义是最终
final变量是常量,不能改变
final方法不能重写
final类不能被继承
目的就是不让他们发生改变
final方法
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
使用final方法的原因:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
final常量
用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。