类和对象
类
在Java中一切皆对象,一切都围绕对象进行,找对象、建对象,用对象等
类:把具有相同属性和行为的一类对象抽象为类。类是抽象概念,如人类、犬类等,无法具体到每个实体。
对象:某个类的一个实体,当有了对象后,这些属性便有了属性值,行为也就有了相应的意义。
类是描述某一对象的统称,对象是这个类的一个实例而已。有类之后就能根据这个类来产生具体的对象。一类对象所具备的共同属性和行为(方法)都在类中定义。
实例化过程
实例化一个对象
//定义一个Person对象
public class Person {
//成员变量可以没有初始化值,因为不同的对象其值不同
public String Name;
public int Age;
public int height;
public String Sex;
//成员方法:访问控制 返回值类型 标识符(参数列表){方法体}
public void eat(String food) {
// TODO Auto-generated method stub
System.out.println(Name+""+food);
}
public void print() {
// TODO Auto-generated method stub
}
}
封装
封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装的优点
-
- 良好的封装能够减少耦合。
-
- 类内部的结构可以自由修改。
-
- 可以对成员变量进行更精确的控制。
-
- 隐藏信息,实现细节。
访问控制权限
-
private(私有的):被private 修饰的属性和方法,只在当前类可见,出了类的{ },对外就完全隐藏了,外部不知道有其存在。。
-
default(不需要写这个关键字,什么权限也没有(包访问权限))
-
protected(友元访问)要么是继承关系,要么是同一个包下都可访问
-
public(公共的、公开的):被public 修饰的,在当前程序(项目)中都是可见并且可以使用的。
public | protected | package(默认) | private | |
---|---|---|---|---|
所有位置 | √ | x | x | x |
继承 | √ | √ | x | x |
同包 | √ | √ | √ | x |
本类 | √ | √ | √ | √ |
public class EncapTest{
private String name;
private String idNum;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String getIdNum(){
return idNum;
}
public void setAge( int newAge){
age = newAge;
}
public void setName(String newName){
name = newName;
}
public void setIdNum( String newId){
idNum = newId;
}
}
构造方法
1、构造方法:构造方法是类中非常特殊的一类方法,使用关键字new 实例化对象时实际上调用的就是该类的构造方法。
2.构造方法的作用就是产生对象
3.使用new关键字产生一个对象时,大致分为以下两步:
(1)为对象在堆中分配空间(空间大小由该类中成员变量的属性决定)
(2)调用对象的构造方法为对象成员变量赋值(当构造方法调用结束后,该对象初始化完成)
注意:构造方法要和类名一致,没有返回值
public class Animal {
private int Price;
private String Name;
private int Age;
public Animal() {
System.out.println("这是Animal的构造方法");
}
}
public static void main(String[] args) {
Animal an=new Animal();
System.out.println(an.getName());
}
this 关键字(表示当前对象的引用)
this关键字调用当前对象的成员变量
ublic class Animal {
private int Price;
private String Name;
private int Age;
public Animal(int Price,String Name,int Age) {
System.out.println("这是Animal的构造方法");
this.Age=Age;
this.Name=Name;
this.Price=Price;
}
}
public static void main(String[] args) {
Animal an=new Animal(1200,"金毛",12);
System.out.println(an.getName());
System.out.println(an.getPrice());
System.out.println(an.getAge());
}
为什么通过构造方法给成员变量初始化了,但输出结果仍是默认值?
形参名称与成员变量名称相同。程序设计理念:就近匹配原则,编译器会找最近的相同名称的变量在哪
final关键字
final关键字:final关键字,能修饰类,方法,属性,局部变量 final关键字修饰类,和方法
final不能改变在内存中的地址引用
-
fianal修饰的变量不可被修改(当常量去理解)
-
fianal修饰的方法不可被重写
-
fianal修饰的类不可被继承
static关键字
static 关键字: 叫做静态关键字,有静态关键字和动态区分出来
static 关键字:可以修饰(内部类),方法,属性,代码块
static 关键字的含义是,当类加载器,在加载这个类型模板的时候,就在方法区的元数区中开辟内存空间,并设置好值
这样做的话,static修饰的属性,就可以在没有对象的情况下被调用,static修饰的方法,也可以在没有对象的时候被调用(因为已经没有内存空间存这个东西了) 但是又由于,这个内存空间的开辟,只进行了一次,所以所有其他对象用这个属性的时候,用的都是同一个内存空间
static也叫类变量或类方法,有且仅有一个,而且只执行一次
在继承过程中通过类名调用父类中定义的类的属性和类方法,只加载父类到jvm中(换而言之,就是只有父类的静态代码块会执行)
继承(本质扩展)
继承,通俗点来说就是 子承父业。是使用已存在的类的定义作为基础,建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类中的某些属性,除了父类中私有的属性和方法,子类必须全部继承。
-
被继承的类称为父类(超类),继承父类的类称为子类(派生类)使用 关键字extends 继承。
-
子类拥有父类非 private 的属性、方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法(即方法的重写/覆盖)。
-
构造器而言,它只能够被调用,而不能被继承,子类可以使用super()调用父类构造器。
-
对于继承而已,子类会默认调用父类的无参构造,但是如果父类没有无参构造,子类必须要在其构造方法中的第一行代码调用指定父类的构造器,传递对应参数。
-
java 的继承是单继承,允许链继承
-
继承过程中,访问权限可改变(可大不可小);
class Father{
//父类中的非私有属性都会被继承
public int age;
private double money;
String home;
//父类中的非私有方法都会被继承
void eat() {} //吃东西
public void sleep() {}//睡觉
private void soner() {}//打呼噜
//父类构造方法如果有参数,子类必须在构造方法第一行中调用
public Father(int x) {
//父类如果写了有参构造,那么默认的无参构造将不再生效
}
}
class Son extends Father{
public Son(int x) {
super(x);//调用父类构造 super()
age=12;//继承后拥有父类的属性
home="王者峡谷河道下边的草丛";
//money=3.0; 父类私有属性无法访问
sleep();//可以执行父类中的非私有方法
}
}
类继承父类,默认在子类构造方法中调用父类构造,在创建子类实例对象时,实际上的执行顺序是(父类构造——子类构造)。
public static void main(String[] args) {
Z z1 = new Z();//创建子类实例对象时,实际上的执行顺序
}
}
class F {
static {
//静态代码块,只有方法的大括号,没有方法名返回值等任何内容
System.out.println("父类静态代码块");
}
{
//构造代码块,只有方法的大括号,没有方法名返回值等任何内容
System.out.println("父类构造代码块");
}
public F() {
// 父类构造器
System.out.println("父类构造器");
}
}
class Z extends F{
static {
//静态代码块,只有方法的大括号,没有方法名返回值等任何内容
System.out.println("子类静态代码块");
}
{
//构造代码块,只有方法的大括号,没有方法名返回值等任何内容
System.out.println("子类构造代码块");
}
public Z() {
// 父类构造器
System.out.println("子类构造器");
}
}
运行结果:
父类静态代码块
子类静态代码块
父类构造代码块
父类构造器
子类构造代码块
子类构造器
final关键字
-
fianal修饰的变量不可被修改(当常量去理解)
-
fianal修饰的方法不可被重写
-
fianal修饰的类不可被继承
抽象
被abstract修饰的方法叫抽象方法
抽象类可以承载抽象方法
抽象方法的含义是当前类型不知道如何实现这个方法,应该由子类去实现
抽象方法由子类去重写
-
抽象方法没有方法体,直接由分号截断方法
2.抽象方法只能放在抽象类里
public abstract void eat();
匿名类
public abstract class Animal {
public String name;
public int age;
public abstract void eat();
}
public class Main {
public static void main(String[] args) {
Animal an=new Animal(null, 0) {
@Override
public void eat() {
}
};
}
}
抽象类和普通类的比较
-
相同点:普通类和抽象类里面可以有常量、变量、构造方法、方法、静态代码块;
-
不同点:抽象类里面可以存放抽象方法,并且抽象方法不能直接创建对象;
接口
接口既没有构造方法也没有静态代码块
接口可以多继承
接口里可以有default默认方法
多态
一种对象多种表现形式
public static void main(String[] args) {
Person p1=new Pcoach("杨教练", 50);
((Pcoach)p1).teach();
((Pcoach)p1).studyEnglish();
Person p2=new Pplayer("杨WY", 50);
((Pplayer)p2).sport();
((Pplayer)p2).studyEnglish();
Bcoach b1=new Bcoach("吴教练",55);
b1.teach();
Bplayer b2=new Bplayer("吴zx",55);
b2.sport();
}
重载
方法名相同,形参数列表不同(即参数类型不同,个数不同,顺序不同三个条件符合一个)
public void foo() {
}
public int foo(int a) {
return a;
}
public int foo(int a,String b) {
return a;
}
public int foo(String b,int a) {
return a;
}
toString
System.out.println(b1.toString());
public String toString() {
return "Bcoach [name=" + name + ", age=" + age + "]";
}
“ = = ”
双等于是判断两个变量在堆中的内存地址是否一样
String str="123";
String str1=new String();
System.out.println(str == str1);
输出结果:
false
equals
判断两个对象的值是否相等
String str="123";
String str1=new String();
System.out.println(str.equals(str1));
输出结果:
ture
instanof
判断两个对象是否是同一类型
hashCode
如果两个对象是相等的(eauals的返回值是ture)那么要求hashCode也一定相等
如果两个对象的hashCode不相等,那么这两个对象一定不相等
如果两个对象的hashCode的值相等,那么两个对象不一定相等(因为hashCode是一个int值,有)
如果两个对象不相等,那么两个对象的hashCode值也可能相等也可能不相等